avoid reading uninitialized memory in __map_file
[musl] / src / ldso / dynlink.c
index 0c3b36c..cab3008 100644 (file)
@@ -1543,8 +1543,10 @@ _Noreturn void __dls3(size_t *sp)
                if (!app.loadmap) {
                        app.loadmap = (void *)&app_dummy_loadmap;
                        app.loadmap->nsegs = 1;
-                       app.loadmap->segs[0].addr = (size_t)app.base;
-                       app.loadmap->segs[0].p_memsz = -1;
+                       app.loadmap->segs[0].addr = (size_t)app.map;
+                       app.loadmap->segs[0].p_vaddr = (size_t)app.map
+                               - (size_t)app.base;
+                       app.loadmap->segs[0].p_memsz = app.map_len;
                }
                argv[-3] = (void *)app.loadmap;
        }
@@ -1738,6 +1740,28 @@ static int invalid_dso_handle(void *h)
        return 1;
 }
 
+static void *addr2dso(size_t a)
+{
+       struct dso *p;
+       for (p=head; p; p=p->next) {
+               if (DL_FDPIC && p->loadmap) {
+                       size_t i;
+                       for (i=0; i<p->loadmap->nsegs; i++) {
+                               if (a-p->loadmap->segs[i].p_vaddr
+                                   < p->loadmap->segs[i].p_memsz)
+                                       return p;
+                       }
+                       i = count_syms(p);
+                       if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
+                               return p;
+               } else {
+                       if (a-(size_t)p->map < p->map_len)
+                               return p;
+               }
+       }
+       return 0;
+}
+
 void *__tls_get_addr(size_t *);
 
 static void *do_dlsym(struct dso *p, const char *s, void *ra)
@@ -1749,7 +1773,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
                if (p == RTLD_DEFAULT) {
                        p = head;
                } else if (p == RTLD_NEXT) {
-                       for (p=head; p && (unsigned char *)ra-p->map>p->map_len; p=p->next);
+                       p = addr2dso((size_t)ra);
                        if (!p) p=head;
                        p = p->next;
                }
@@ -1806,7 +1830,7 @@ int __dladdr(const void *addr, Dl_info *info)
        char *bestname;
 
        pthread_rwlock_rdlock(&lock);
-       for (p=head; p && (unsigned char *)addr-p->map>p->map_len; p=p->next);
+       p = addr2dso((size_t)addr);
        pthread_rwlock_unlock(&lock);
 
        if (!p) return 0;