diff options
author | dfr <dfr@FreeBSD.org> | 2005-03-30 08:28:26 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2005-03-30 08:28:26 +0000 |
commit | cfeb84df7a91a688a57f22740ad89d7dd6a228da (patch) | |
tree | 8f422e1a88bdcadf78e18022780642484798cfde /libexec | |
parent | 75d6caaaf0e3d97f38d128fc5f7c7adfe451f2c7 (diff) | |
download | FreeBSD-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.c | 12 |
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]); } } |