Skip to content

Commit

Permalink
i#6541 privlib: Add try/except around private library init/fini
Browse files Browse the repository at this point in the history
Wraps private library init/fini calls in a try/except on Linux (as is
already done on Windows) and reports a crash as a SYSLOG_ERROR
pointing at the library's name.  This is much better than a weird
assert or mysterious secondary crash later.

Adds a check for shared_data==NULL in check_thread_in_last_vmwarea()
to avoid a crash seen there.

Issue: #6541
  • Loading branch information
derekbruening committed Jan 5, 2024
1 parent eaac7d5 commit aa74d7f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 10 deletions.
21 changes: 13 additions & 8 deletions core/unix/loader.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* *******************************************************************************
* Copyright (c) 2011-2023 Google, Inc. All rights reserved.
* Copyright (c) 2011-2024 Google, Inc. All rights reserved.
* Copyright (c) 2011 Massachusetts Institute of Technology All rights reserved.
* *******************************************************************************/

Expand Down Expand Up @@ -157,7 +157,7 @@ static privmod_t *
privload_locate_and_load(const char *impname, privmod_t *dependent, bool reachable);

static void
privload_call_lib_func(fp_t func);
privload_call_lib_func(dcontext_t *dcontext, privmod_t *privmod, fp_t func);

static void
privload_relocate_mod(privmod_t *mod);
Expand Down Expand Up @@ -618,15 +618,15 @@ privload_call_entry(dcontext_t *dcontext, privmod_t *privmod, uint reason)
if (opd->init != NULL) {
LOG(GLOBAL, LOG_LOADER, 4, "%s: calling %s init func " PFX "\n", __FUNCTION__,
privmod->name, opd->init);
privload_call_lib_func(opd->init);
privload_call_lib_func(dcontext, privmod, opd->init);
}
if (opd->init_array != NULL) {
uint i;
for (i = 0; i < opd->init_arraysz / sizeof(opd->init_array[i]); i++) {
if (opd->init_array[i] != NULL) { /* be paranoid */
LOG(GLOBAL, LOG_LOADER, 4, "%s: calling %s init array func " PFX "\n",
__FUNCTION__, privmod->name, opd->init_array[i]);
privload_call_lib_func(opd->init_array[i]);
privload_call_lib_func(dcontext, privmod, opd->init_array[i]);
}
}
}
Expand All @@ -648,15 +648,15 @@ privload_call_entry(dcontext_t *dcontext, privmod_t *privmod, uint reason)
if (opd->fini != NULL) {
LOG(GLOBAL, LOG_LOADER, 4, "%s: calling %s fini func " PFX "\n", __FUNCTION__,
privmod->name, opd->fini);
privload_call_lib_func(opd->fini);
privload_call_lib_func(dcontext, privmod, opd->fini);
}
if (opd->fini_array != NULL) {
uint i;
for (i = 0; i < opd->fini_arraysz / sizeof(opd->fini_array[0]); i++) {
if (opd->fini_array[i] != NULL) { /* be paranoid */
LOG(GLOBAL, LOG_LOADER, 4, "%s: calling %s fini array func " PFX "\n",
__FUNCTION__, privmod->name, opd->fini_array[i]);
privload_call_lib_func(opd->fini_array[i]);
privload_call_lib_func(dcontext, privmod, opd->fini_array[i]);
}
}
}
Expand Down Expand Up @@ -1064,7 +1064,7 @@ get_private_library_address(app_pc modbase, const char *name)
}

static void
privload_call_lib_func(fp_t func)
privload_call_lib_func(dcontext_t *dcontext, privmod_t *privmod, fp_t func)
{
char dummy_str[] = "dummy";
char *dummy_argv[2];
Expand All @@ -1076,7 +1076,12 @@ privload_call_lib_func(fp_t func)
*/
dummy_argv[0] = dummy_str;
dummy_argv[1] = NULL;
func(1, dummy_argv, our_environ);
TRY_EXCEPT_ALLOW_NO_DCONTEXT(
dcontext, { func(1, dummy_argv, our_environ); },
{ /* EXCEPT */
SYSLOG_INTERNAL_ERROR("Private library %s init/fini func " PFX " crashed",
privmod->name, func);
});
}

bool
Expand Down
4 changes: 2 additions & 2 deletions core/vmareas.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2010-2023 Google, Inc. All rights reserved.
* Copyright (c) 2010-2024 Google, Inc. All rights reserved.
* Copyright (c) 2002-2010 VMware, Inc. All rights reserved.
* **********************************************************/

Expand Down Expand Up @@ -8385,7 +8385,7 @@ check_in_last_thread_vm_area(dcontext_t *dcontext, app_pc pc)
data->last_area->start <= pc);
}
/* last decoded app pc may be in last shared area instead */
if (!in_last && DYNAMO_OPTION(shared_bbs)) {
if (!in_last && DYNAMO_OPTION(shared_bbs) && shared_data != NULL) {
/* We avoid the high-ranked shared_vm_areas lock which can easily cause
* rank order violations (i#3346). We're trying to catch the scenario
* where a shared bb is being built and we fault decoding it. There,
Expand Down

0 comments on commit aa74d7f

Please sign in to comment.