Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
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.