Skip to content

_sqlite: NULL deref in sqlite3_changes() when connection is closed during executemany() #145046

@raminfp

Description

@raminfp

Bug report

Bug description:

A segmentation fault occurs in the _sqlite module when a connection is closed during executemany().

After sqlite3_step() completes inside _pysqlite_query_execute(), the code calls:

sqlite3_changes(self->connection->db);

However, if the connection was closed during statement execution (for example via a callback, user-defined function), self->connection->db may already be NULL.

This results in a NULL pointer dereference inside sqlite3_changes() , causing a segmentation fault.

The crash happens because ‍_pysqlite_query_execute() does not verify that self->connection->db is still valid before calling SQLite APIs after execution.

Affected Code

Modules/_sqlite/cursor.c:961

self->rowcount += (long)sqlite3_changes(self->connection->db);

Reproducer

import sqlite3

conn = sqlite3.connect(":memory:", autocommit=True)
conn.execute("CREATE TABLE t(x)")

def call_func(x):
    conn.close()
    return x

conn.create_function("raminfp", 1, call_func)
conn.executemany("INSERT INTO t VALUES(raminfp(?))", [(i,) for i in range(10)])

ASAN

AddressSanitizer:DEADLYSIGNAL
=================================================================
==141385==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000078 (pc 0x723b9b28d044 bp 0x7ffde3a8ee60 sp 0x7ffde3a8ee58 T0)
==141385==The signal is caused by a READ memory access.
==141385==Hint: address points to the zero page.
    #0 0x723b9b28d044 in sqlite3_changes64 (/lib/x86_64-linux-gnu/libsqlite3.so.0+0xaa044) (BuildId: f5959b839b5d4de9879dc3630ecde4d76d4be713)
    #1 0x723b9b28d05c in sqlite3_changes (/lib/x86_64-linux-gnu/libsqlite3.so.0+0xaa05c) (BuildId: f5959b839b5d4de9879dc3630ecde4d76d4be713)
    #2 0x723b9cb49548 in _pysqlite_query_execute Modules/_sqlite/cursor.c:961
    #3 0x723b9cb420d9 in pysqlite_connection_executemany_impl Modules/_sqlite/connection.c:1881
    #4 0x723b9cb42255 in pysqlite_connection_executemany Modules/_sqlite/clinic/connection.c.h:1002
    #5 0x5887c9f97cd6 in method_vectorcall_FASTCALL Objects/descrobject.c:402
    #6 0x5887c9f77ccc in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #7 0x5887c9f77dbf in PyObject_Vectorcall Objects/call.c:327
    #8 0x5887ca1f68b7 in _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:769
    #9 0x5887ca20687b in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1817
    #10 0x5887ca23dab0 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #11 0x5887ca23de16 in _PyEval_Vector Python/ceval.c:2132
    #12 0x5887ca23e0cc in PyEval_EvalCode Python/ceval.c:680
    #13 0x5887ca341771 in run_eval_code_obj Python/pythonrun.c:1366
    #14 0x5887ca341ab7 in run_mod Python/pythonrun.c:1469
    #15 0x5887ca3429ec in pyrun_file Python/pythonrun.c:1294
    #16 0x5887ca345822 in _PyRun_SimpleFileObject Python/pythonrun.c:518
    #17 0x5887ca345ace in _PyRun_AnyFileObject Python/pythonrun.c:81
    #18 0x5887ca39adf6 in pymain_run_file_obj Modules/main.c:410
    #19 0x5887ca39b063 in pymain_run_file Modules/main.c:429
    #20 0x5887ca39c861 in pymain_run_python Modules/main.c:691
    #21 0x5887ca39cef7 in Py_RunMain Modules/main.c:772
    #22 0x5887ca39d0e3 in pymain_main Modules/main.c:802
    #23 0x5887ca39d468 in Py_BytesMain Modules/main.c:826
    #24 0x5887c9e02675 in main Programs/python.c:15
    #25 0x723b9d62a3b7 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #26 0x723b9d62a47a in __libc_start_main_impl ../csu/libc-start.c:360
    #27 0x5887c9e025a4 in _start (/home/raminfp/Projects/cpython/python+0x2ee5a4) (BuildId: e49fbf8445afdc42fe85d33b45e06c327d194e63)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libsqlite3.so.0+0xaa044) (BuildId: f5959b839b5d4de9879dc3630ecde4d76d4be713) in sqlite3_changes64
==141385==ABORTING

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions