Skip to content

Fix ZTS crashes with persistent resources in modules #13381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions TSRM/TSRM.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,27 @@ void ts_free_id(ts_rsrc_id id)
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully freed resource id %d", id));
}/*}}}*/

TSRM_API void ts_callback_id(ts_rsrc_id id, void (*cb)(void *))
{
int rsrc_id = TSRM_UNSHUFFLE_RSRC_ID(id);

tsrm_mutex_lock(tsmm_mutex);

if (tsrm_tls_table && resource_types_table) {
for (int i = 0; i < tsrm_tls_table_size; i++) {
tsrm_tls_entry *p = tsrm_tls_table[i];

while (p) {
if (p->count > rsrc_id && p->storage[rsrc_id]) {
cb(p->storage[rsrc_id]);
}
p = p->next;
}
}
}

tsrm_mutex_unlock(tsmm_mutex);
}

/*
* Utility Functions
Expand Down
3 changes: 3 additions & 0 deletions TSRM/TSRM.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ TSRM_API void ts_free_thread(void);
/* deallocates all occurrences of a given id */
TSRM_API void ts_free_id(ts_rsrc_id id);

/* Runs a callback on all resources of the given id.
* The caller is responsible for ensuring the underlying resources don't data-race. */
TSRM_API void ts_callback_id(ts_rsrc_id id, void (*cb)(void *));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would propose to think about a better name. e.g. ts_apply_for_id()


/* Debug support */
#define TSRM_ERROR_LEVEL_ERROR 1
Expand Down
13 changes: 11 additions & 2 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,13 +826,19 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
}
/* }}} */

static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{{ */
static void executor_globals_persistent_list_dtor(void *storage)
{
zend_ini_dtor(executor_globals->ini_directives);
zend_executor_globals *executor_globals = storage;

if (&executor_globals->persistent_list != global_persistent_list) {
zend_destroy_rsrc_list(&executor_globals->persistent_list);
}
}

static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{{ */
{
zend_ini_dtor(executor_globals->ini_directives);

if (executor_globals->zend_constants != GLOBAL_CONSTANTS_TABLE) {
zend_hash_destroy(executor_globals->zend_constants);
free(executor_globals->zend_constants);
Expand Down Expand Up @@ -1122,6 +1128,9 @@ void zend_shutdown(void) /* {{{ */
zend_vm_dtor();

zend_destroy_rsrc_list(&EG(persistent_list));
#ifdef ZTS
ts_callback_id(executor_globals_id, executor_globals_persistent_list_dtor);
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably may be changed into (I'm not completely sure)

#ifndef ZTS
	zend_destroy_rsrc_list(&EG(persistent_list));
#else
	ts_callback_id(executor_globals_id, executor_globals_persistent_list_dtor);
#endif

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just quickly tested this by printing out all the lists that get destroyed, and I see that it now misses the global_persistent_list whereas it previously was destroyed by zend_destroy_rsrc_list(&EG(persistent_list));. So this seems wrong.

zend_destroy_modules();

virtual_cwd_deactivate();
Expand Down
8 changes: 1 addition & 7 deletions ext/odbc/php_odbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,7 @@ static void _close_odbc_conn(zend_resource *rsrc)
SQLFreeEnv(conn->henv);
}
efree(conn);
/* See https://github.com/php/php-src/issues/12974 why we need to check the if */
#ifdef ZTS
if (odbc_module_entry.module_started)
#endif
{
ODBCG(num_links)--;
}
ODBCG(num_links)--;
}
/* }}} */

Expand Down
10 changes: 2 additions & 8 deletions ext/pgsql/pgsql.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,8 @@ static void _close_pgsql_plink(zend_resource *rsrc)
PQclear(res);
}
PQfinish(link);
/* See https://github.com/php/php-src/issues/12974 why we need to check the if */
#ifdef ZTS
if (pgsql_module_entry.module_started)
#endif
{
PGG(num_persistent)--;
PGG(num_links)--;
}
PGG(num_persistent)--;
PGG(num_links)--;
rsrc->ptr = NULL;
}

Expand Down