summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2005-03-30 08:28:26 +0000
committerdfr <dfr@FreeBSD.org>2005-03-30 08:28:26 +0000
commitcfeb84df7a91a688a57f22740ad89d7dd6a228da (patch)
tree8f422e1a88bdcadf78e18022780642484798cfde /libexec
parent75d6caaaf0e3d97f38d128fc5f7c7adfe451f2c7 (diff)
downloadFreeBSD-src-cfeb84df7a91a688a57f22740ad89d7dd6a228da.zip
FreeBSD-src-cfeb84df7a91a688a57f22740ad89d7dd6a228da.tar.gz
When allocating TLS and DTV, make sure that any unused slots in the DTV
are initialised to zero. When freeing TLS, don't attempt to free DTV slots which were not used. Pointed out by: Joerg Sonnenberger X-MFC-After: After the branch, probably
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/rtld.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 584576d..1db0227 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2560,7 +2560,7 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign)
size = tls_static_space;
tls = malloc(size);
- dtv = malloc((tls_max_index + 2) * sizeof(Elf_Addr));
+ dtv = calloc(1, (tls_max_index + 2) * sizeof(Elf_Addr));
*(Elf_Addr**) tls = dtv;
@@ -2601,8 +2601,6 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign)
memcpy((void*) addr, obj->tlsinit,
obj->tlsinitsize);
dtv[obj->tlsindex + 1] = addr;
- } else if (obj->tlsindex) {
- dtv[obj->tlsindex + 1] = 0;
}
}
}
@@ -2629,7 +2627,7 @@ free_tls(void *tls, size_t tcbsize, size_t tcbalign)
tlsstart = (Elf_Addr) tls;
tlsend = tlsstart + size;
for (i = 0; i < dtvsize; i++) {
- if (dtv[i+2] < tlsstart || dtv[i+2] > tlsend) {
+ if (dtv[i+2] && (dtv[i+2] < tlsstart || dtv[i+2] > tlsend)) {
free((void*) dtv[i+2]);
}
}
@@ -2659,7 +2657,7 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign)
assert(tcbsize >= 2*sizeof(Elf_Addr));
tls = malloc(size + tcbsize);
- dtv = malloc((tls_max_index + 2) * sizeof(Elf_Addr));
+ dtv = calloc(1, (tls_max_index + 2) * sizeof(Elf_Addr));
segbase = (Elf_Addr)(tls + size);
((Elf_Addr*)segbase)[0] = segbase;
@@ -2703,8 +2701,6 @@ allocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign)
if (obj->tlsinit)
memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize);
dtv[obj->tlsindex + 1] = addr;
- } else if (obj->tlsindex) {
- dtv[obj->tlsindex + 1] = 0;
}
}
}
@@ -2731,7 +2727,7 @@ free_tls(void *tls, size_t tcbsize, size_t tcbalign)
tlsend = (Elf_Addr) tls;
tlsstart = tlsend - size;
for (i = 0; i < dtvsize; i++) {
- if (dtv[i+2] < tlsstart || dtv[i+2] > tlsend) {
+ if (dtv[i+2] && (dtv[i+2] < tlsstart || dtv[i+2] > tlsend)) {
free((void*) dtv[i+2]);
}
}
OpenPOWER on IntegriCloud