|
Message-ID: <869863DB5440B44FB22173F42FC3F3CE01D0843A@dggemm513-mbx.china.huawei.com>
Date: Wed, 19 Jun 2019 07:13:18 +0000
From: "liucheng (G)" <liucheng32@...wei.com>
To: "musl@...ts.openwall.com" <musl@...ts.openwall.com>
CC: "liucheng (G)" <liucheng32@...wei.com>
Subject: [PATCH] The local variables "sym" and "bestsym" in dladdr
function are assigned initial values to NULL
Dear all,
The code bellow in the dladdr function has different behaviors at different optimization levels.
2219 if (bestsym && besterr > bestsym->st_size-1) {
2220 best = 0;
2221 bestsym = 0;
2222 }
Case of O1(arm32 little-endian):
154: e3580000 cmp r8, #0
158: 0a000003 beq 16c <dladdr+0x16c>
15c: e5983008 ldr r3, [r8, #8]
160: e2433001 sub r3, r3, #1
164: e153000a cmp r3, sl
168: 3a000011 bcc 1bc <dladdr+0x1b4>
Case of O2:
75e00: e5942044 ldr r2, [r4, #68] ; 0x44
75e04: e2433001 sub r3, r3, #1
75e08: e5941004 ldr r1, [r4, #4]
75e0c: e1530009 cmp r3, r9
75e10: 2a000007 bcs 75e34 <dladdr+0xfc>
75e14: e8870006 stm r7, {r1, r2}
In case of O2, the first part "bestsym" has been optimized, which may cause segment fault.
[patch]
Signed-off-by: l00383200 <liucheng32@...wei.com<mailto:liucheng32@...wei.com>>
---
ldso/dynlink.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 7cb66db..c5f5fb7 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -2175,7 +2175,8 @@ int dladdr(const void *addr_arg, Dl_info *info)
{
size_t addr = (size_t)addr_arg;
struct dso *p;
- Sym *sym, *bestsym;
+ Sym *sym = NULL;
+ Sym *bestsym = NULL;
uint32_t nsym;
char *strings;
size_t best = 0;
--
1.8.5.6
[testcase]
------------
#define _GNU_SOURCE
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
static int callback(struct dl_phdr_info *info, size_t size, void *data)
{
int j,ret;
printf ("name=%s (%d segments)\n", info->dlpi_name, info->dlpi_phnum);
if(!strcmp(info->dlpi_name,"/lib/ld-musl-arm.so.1")) {
printf("ld-musl-arm have no indo\n");
return 0;
}
for (j = 0; j < info->dlpi_phnum; j++) {
void* addr = (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr);
printf ("\t\t header %2d: address=%10p\n", j, addr);
Dl_info dlinfo;
ret = dladdr(addr, &dlinfo);
printf("\t\t\t %s : %s.", dlinfo.dli_fname, dlinfo.dli_sname);
if((addr == NULL && ret == 0) || (addr != NULL && ret == 1)) {
printf(" dladdr pass return:%d\n",ret);
} else {
printf(" dladdr error return:%d\n",ret);
}
}
return 0;
}
int main (int argc, char *argv[])
{
dl_iterate_phdr(callback, NULL);
exit(EXIT_SUCCESS);
}
------------
Content of type "text/html" skipped
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.