python / python/cpython

sqlite3 Connection and Cursor segfault if __init__ is bypassed (by subclass or __new__ call)

Abierto
#152,954 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

extension-modules topic-sqlite3 type-crash
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Crash report

What happened?
import sqlite3
con = sqlite3.Connection.__new__(sqlite3.Connection)
print(con.row_factory)

or, more likely:

import sqlite3
class MyCon(sqlite3.Connection):
  def __init__(self, *a, **kw):
    if self.row_factory:
      pass
    super().__init__()
c = MyCon(':memory:')

Both give:

fish: Job 1, './python.exe repro.py' terminated by signal SIGSEGV (Address boundary error)

LLDB:

Process 76976 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
       frame #0: 0x0000000100a93df0 _sqlite3.cpython-316d-darwin.so`Py_INCREF(op=0x0000000000000000) at refcount.h:286:31 [opt] [inlined]
   283 	        _Py_atomic_add_ssize(&op->ob_ref_shared, (1 << _Py_REF_SHARED_SHIFT));
   284 	    }
   285 	#elif SIZEOF_VOID_P > 4
-> 286 	    uint32_t cur_refcnt = op->ob_refcnt;
   287 	    if (cur_refcnt >= _Py_IMMORTAL_INITIAL_REFCNT) {
   288 	        // the object is immortal
   289 	        _Py_INCREF_IMMORTAL_STAT_INC();
Target 0: (python.exe) stopped.
warning: _sqlite3.cpython-316d-darwin.so was compiled with optimization - stepping may behave oddly; variables may not be available.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
   * frame #0: 0x0000000100a93df0 _sqlite3.cpython-316d-darwin.so`Py_INCREF(op=0x0000000000000000) at refcount.h:286:31 [opt] [inlined]
     frame #1: 0x0000000100a93df0 _sqlite3.cpython-316d-darwin.so`_Py_NewRef(obj=0x0000000000000000) at refcount.h:536:5 [opt] [inlined]
     frame #2: 0x0000000100a93df0 _sqlite3.cpython-316d-darwin.so`connection_get_row_factory(op=0x0000007a371d4040, closure=0x0000000000000000) at connection.c:564:12 [opt]

So, basically, until the tp_init is called, both row_factory and text_factory are NULL, but are treated as always being python objects, causing a number of segfaults.

This was discovered when fixing: gh-152817 / gh-152818 which was a follow-on from: gh-149738 / gh-149754

I think the fix here is to add a tp_new that initializes the fields before python has a chance to mess with the object, and then rely on the associated guards that prevent delattr on those fields (in the above PRs)

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.16.0a0 (heads/main-dirty:c4739533f33, Jul 3 2026, 12:34:46) [Clang 21.0.0 (clang-2100.3.20.102)]

Linked PRs
  • gh-152956

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con la implementación de la conexión de sqlite3 en connection.c, especialmente con connection_get_row_factory, y revisa el reproducer que muestra el acceso antes de tp_init. Comprueba el PR enlazado gh-152956 y ejecuta los ejemplos de new y de subclass indicados. El trabajo estará terminado cuando estos casos ya no produzcan un segfault y las pruebas relevantes de sqlite3 los cubran.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
c, python
Área
databases
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.