/ Ticket Change Details
Login
Overview

Artifact ID: 580eefd3a106fa0817ae2c2b25797a9841fc8b8938e6df86f44b4b878334c885
Ticket: be436a7f4587ce517ddc36f3670073563ecc6622
Use-after-free on schema change where RTREE is used inside of a trigger
User & Date: drh 2017-08-17 02:25:13
Changes

  1. Change icomment to:

    If a virtual table invokes sqlite3_step() as part of its xConnect method (as RTREE does) and if that virtual table is used inside of a trigger and if an external schema change occurs on the first use of that trigger, then the xConnect method will provoke a schema reset that will delete a pointer to the trigger out from under the query planner, resulting in a use-after-free and a probable segfault. The following C code demonstrates the problems:

    #include <stdio.h>
    #include <unistd.h>
    #include "sqlite3.h"
    
    int main(int argc, char *argv){
      sqlite3 *db1, *db2;
      unlink("test.db");
      printf("VERSION: %s\n", sqlite3_libversion());
      sqlite3_open("test.db", &db1);
      sqlite3_exec(db1, 
       "CREATE VIRTUAL TABLE r1 USING rtree(id, x1, x2, y1, y2);\n"
       "CREATE TABLE t1(id, x1, x2, y1, y2);\n"
       "CREATE TABLE log(l);\n"
       "CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN\n"
       "  INSERT INTO r1 VALUES(new.id, new.x1, new.x2, new.y1, new.y2);\n"
       "  INSERT INTO log VALUES('r1: ' || new.id);\n"
       "END;", 0, 0, 0);
      sqlite3_close(db1);
      sqlite3_open("test.db", &db1);
      sqlite3_open("test.db", &db2);
      sqlite3_exec(db1, "INSERT INTO log VALUES('startup');", 0, 0, 0);
      sqlite3_exec(db2, "CREATE TABLE newtab(a,b);", 0, 0, 0);
      sqlite3_exec(db1, "INSERT INTO t1 VALUES(1,2,3,4,5);", 0, 0, 0);
      sqlite3_close(db1);
      sqlite3_close(db2);
      return 0;
    }
    

    This problem appears to have existed in the virtual table implementation forever. The test program above first began to fail with check-in [ebc9433f] on 2010-02-16 (SQLite version 3.6.23) because that check-in was the first to cause RTREE to invoke sqlite3_step() from within its xConnect method.

  2. Change login to "drh"
  3. Change mimetype to "text/x-fossil-wiki"
  4. Change severity to "Severe"
  5. Change status to "Open"
  6. Change title to:

    Use-after-free on schema change where RTREE is used inside of a trigger

  7. Change type to "Code_Defect"