php / php/php-src

A crash occurred in the odbc_handle_closer function

Ouverte
#20,726 10 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug Extension: pdo_odbc Status: Needs Triage
Langage dominant
C
Étoiles
40.4k
Forks
8.2k
Merge moyen
2 j 13 h
PR mergées (30 j)
96

Description

There is an issue with the order of resource release that needs to be corrected by modifying the code.

https://github.com/php/php-src/blob/833120eb72295fd9a6d0cacc68e85cbbeaa6a535/ext/pdo_odbc/odbc_driver.c#L138

The correct code might be:

static void odbc_handle_closer(pdo_dbh_t *dbh) {
    pdo_odbc_db_handle *H = (pdo_odbc_db_handle *) dbh->driver_data;

    SQLFreeHandle(SQL_HANDLE_ENV, H->env);
    H->env = NULL;

    if (H->dbc != SQL_NULL_HANDLE) {
        SQLEndTran(SQL_HANDLE_DBC, H->dbc, SQL_ROLLBACK);
        SQLDisconnect(H->dbc);
        SQLFreeHandle(SQL_HANDLE_DBC, H->dbc);
        H->dbc = NULL;
    }

    pefree(H, dbh->is_persistent);
    dbh->driver_data = NULL;
}

I don't quite understand the logic of the ODBC PDO driver, please review the code above.

==45879== Invalid read of size 8
==45879==    at 0x1185F941: ??? (in /usr/lib/libodbccr.so.2.0.0)
==45879==    by 0x734F411: ??? (in /usr/lib/libodbc.so.2.0.0)
==45879==    by 0x7351182: ??? (in /usr/lib/libodbc.so.2.0.0)
==45879==    by 0x7359691: ??? (in /usr/lib/libodbc.so.2.0.0)
==45879==    by 0x7B01E10: odbc_handle_closer (odbc_driver.c:139)
==45879==    by 0x73F800E: ??? (in /usr/lib/php84/modules/pdo.so)
==45879==    by 0x5CE98E: zend_objects_store_del (in /usr/bin/php84)
==45879==    by 0x586F32: ??? (in /usr/bin/php84)
==45879==    by 0x534247: execute_ex (in /usr/bin/php84)
==45879==    by 0x52D64B: zend_call_function (in /usr/bin/php84)
==45879==    by 0x799996A: swoole::PHPCoroutine::main_func(void*) (swoole_coroutine.cc:773)
==45879==    by 0x7A2B6C7: operator() (std_function.h:591)
==45879==    by 0x7A2B6C7: swoole::coroutine::Context::context_func(transfer_t) (context.cc:149)
==45879==  Address 0x11079928 is 2,344 bytes inside a block of size 5,256 free'd
==45879==    at 0x48B2ECF: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==45879==    by 0x73788CA: ??? (in /usr/lib/libodbc.so.2.0.0)
==45879==    by 0x73597E7: ??? (in /usr/lib/libodbc.so.2.0.0)
==45879==    by 0x7B01DFB: odbc_handle_closer (odbc_driver.c:136)
==45879==    by 0x73F800E: ??? (in /usr/lib/php84/modules/pdo.so)
==45879==    by 0x5CE98E: zend_objects_store_del (in /usr/bin/php84)
==45879==    by 0x586F32: ??? (in /usr/bin/php84)
==45879==    by 0x534247: execute_ex (in /usr/bin/php84)
==45879==    by 0x52D64B: zend_call_function (in /usr/bin/php84)
==45879==    by 0x799996A: swoole::PHPCoroutine::main_func(void*) (swoole_coroutine.cc:773)
==45879==    by 0x7A2B6C7: operator() (std_function.h:591)
==45879==    by 0x7A2B6C7: swoole::coroutine::Context::context_func(transfer_t) (context.cc:149)
==45879==    by 0x7B1F70E: swoole_make_fcontext (make_x86_64_sysv_elf_gas.S:135)
==45879==  Block was alloc'd at
==45879==    at 0x48B640A: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==45879==    by 0x7378711: ??? (in /usr/lib/libodbc.so.2.0.0)
==45879==    by 0x734A3EE: ??? (in /usr/lib/libodbc.so.2.0.0)
==45879==    by 0x7B022FE: pdo_odbc_handle_factory (odbc_driver.c:498)
==45879==    by 0x73F2A2D: php_pdo_internal_construct_driver (in /usr/lib/php84/modules/pdo.so)
==45879==    by 0x552BD0: ??? (in /usr/bin/php84)
==45879==    by 0x534247: execute_ex (in /usr/bin/php84)
==45879==    by 0x52D64B: zend_call_function (in /usr/bin/php84)
==45879==    by 0x799996A: swoole::PHPCoroutine::main_func(void*) (swoole_coroutine.cc:773)
==45879==    by 0x7A2B6C7: operator() (std_function.h:591)
==45879==    by 0x7A2B6C7: swoole::coroutine::Context::context_func(transfer_t) (context.cc:149)
==45879==    by 0x7B1F70E: swoole_make_fcontext (make_x86_64_sysv_elf_gas.S:135)

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez dans ext/pdo_odbc/odbc_driver.c, au niveau de odbc_handle_closer autour des lignes 136-139, puis examinez pdo_odbc_handle_factory autour de la ligne 498 ainsi que la trace Valgrind associée. Vérifiez l’ordre de libération des ressources au regard de la lecture invalide signalée et confirmez que le scénario signalé n’accède plus à un état ODBC libéré.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
c, php
Domaine
databases
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Calme
Clarté
Plutôt claire
Accessibilité débutants
52/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.