|
Message-ID: <20190228220129.GA2383@darth.lan> Date: Thu, 28 Feb 2019 23:01:29 +0100 From: Sebastian Kemper <sebastian_ml@....net> To: musl@...ts.openwall.com Cc: Szabolcs Nagy <nsz@...t70.net> Subject: Re: Asterisk 16 segmentation fault On Thu, Feb 28, 2019 at 10:19:02PM +0100, Szabolcs Nagy wrote: > * Sebastian Kemper <sebastian_ml@....net> [2019-02-28 21:27:51 +0100]: > > I'm not a programmer so I have problems making sense of this. So I'm > > hoping that maybe one of you can shine a light. > > it means dlerror() returned 0 and ast_strdupa calls strlen on > this return value which segfaults as expected. > > it is entirely valid for dlerror() to return 0 if there was no > error. did the dlopen("res_pjproject.so", flags) call succeed? > i.e. mod->lib != 0 ?. Hello Szabolcs, Thanks for your reply. And thanks to Rich & Jeffrey as well, of course. Again I'm blown away by how fast one gets a reply on the musl list :-) I stepped through it again and tried to get the value of mod->lib: 952 if (resource_being_loaded) { (gdb) step 951 mod->lib = dlopen(filename, flags); (gdb) step 952 if (resource_being_loaded) { (gdb) p mod->lib $10 = (void *) 0x5fc210 (gdb) p mod->lib $11 = (void *) 0x5fc210 (gdb) p mod->lib $12 = (void *) 0x5fc210 (gdb) p mod->lib $13 = (void *) 0x5fc210 (gdb) p (*mod).lib $14 = (void *) 0x5fc210 (gdb) p (*mod).li There is no member named li. (gdb) p (*mod).lib $15 = (void *) 0x5fc210 (gdb) step 955 const char *dlerror_msg = ast_strdupa(dlerror()); (gdb) step Thread 1 "asterisk" received signal SIGSEGV, Segmentation fault. strlen (s=0x0, s@...ry=0x48d79d <load_dynamic_module+120> "\t\360\"\223\f\234\200\353\216#\005\032\240z\364e") at src/string/strlen.c:17 17 for (w = (const void *)s; !HASZERO(*w); w++); (gdb) So if I'm not mistaken mod->lib is indeed != 0. > e.g. the segfault can be avoided by > > - const char *dlerror_msg = ast_strdupa(dlerror()); > + const char *dlerror_msg = dlerror(); dlerror_msg = ast_strdupa(dlerror_msg ? dlerror_msg : ""); > > but we would need to know what this code is trying to do > (and how it worked before) for a proper fix. astmm.h defines ast_strdupa() like this: #if !defined(ast_strdupa) && defined(__GNUC__) /*! * \brief duplicate a string in memory from the stack * \param s The string to duplicate * * This macro will duplicate the given string. It returns a pointer to the stack * allocatted memory for the new string. */ #define ast_strdupa(s) \ (__extension__ \ ({ \ const char *__old = (s); \ size_t __len = strlen(__old) + 1; \ char *__new = __builtin_alloca(__len); \ memcpy (__new, __old, __len); \ __new; \ })) #endif This define is the same in both Asterisk 15 and 16 (the define only has moved from include/asterisk/utils.h to include/asterisk/astmm.h). The 'static struct ast_module *load_dlopen()' in which it's used has changed, though, between Asterisk 15 and 16: @@ -569,13 +950,60 @@ resource_being_loaded = mod; mod->lib = dlopen(filename, flags); if (resource_being_loaded) { + struct ast_str *list; + int c = 0; + const char *dlerror_msg = ast_strdupa(dlerror()); + resource_being_loaded = NULL; if (mod->lib) { - ast_log(LOG_ERROR, "Module '%s' did not register itself during load\n", resource_in); + module_load_error("Module '%s' did not register itself during load\n", resource_in); logged_dlclose(resource_in, mod->lib); - } else if (!suppress_logging) { - ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror()); + + goto error_return; + } + + if (suppress_logging) { + goto error_return; } + + resource_being_loaded = mod; + mod->lib = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); + if (resource_being_loaded) { + resource_being_loaded = NULL; + + module_load_error("Error loading module '%s': %s\n", resource_in, dlerror_msg); + logged_dlclose(resource_in, mod->lib); + + goto error_return; + } + + list = ast_str_create(64); + if (list) { + if (module_post_register(mod)) { + goto loaded_error; + } + + c = load_dlopen_missing(&list, &mod->requires); + c += load_dlopen_missing(&list, &mod->enhances); +#ifndef OPTIONAL_API + c += load_dlopen_missing(&list, &mod->optional_modules); +#endif + } + + if (list && ast_str_strlen(list)) { + module_load_error("Error loading module '%s', missing %s: %s\n", + resource_in, c == 1 ? "dependency" : "dependencies", ast_str_buffer(list)); + } else { + module_load_error("Error loading module '%s': %s\n", resource_in, dlerror_msg); + } + +loaded_error: + ast_free(list); + unload_dynamic_module(mod); + + return NULL; + +error_return: ast_free(mod); return NULL; @@ -584,12 +1012,11 @@ So 'const char *dlerror_msg' seems to only be used for logging purposes. Should I give the proposed change a spin? I'm off to bed now. I would get back to you tomorrow evening. Again thank you all, much appreciated! With kind regards, Seb
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.