More empty HASH and/or GNU_HASH when Rust-musl
https://github.com/upx/upx/issues/568 modified: p_lx_elf.cpp
This commit is contained in:
parent
540164849b
commit
34df0d6ef1
148
src/p_lx_elf.cpp
148
src/p_lx_elf.cpp
@ -5732,19 +5732,20 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
|
|||||||
unsigned const nbucket = get_te32(&hashtab[0]);
|
unsigned const nbucket = get_te32(&hashtab[0]);
|
||||||
unsigned const *const buckets = &hashtab[2];
|
unsigned const *const buckets = &hashtab[2];
|
||||||
unsigned const *const chains = &buckets[nbucket];
|
unsigned const *const chains = &buckets[nbucket];
|
||||||
if (!nbucket
|
if ((unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image))
|
||||||
|| (unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image))
|
|
||||||
<= sizeof(unsigned)*nbucket ) {
|
<= sizeof(unsigned)*nbucket ) {
|
||||||
char msg[80]; snprintf(msg, sizeof(msg),
|
char msg[80]; snprintf(msg, sizeof(msg),
|
||||||
"bad nbucket %#x\n", nbucket);
|
"bad nbucket %#x\n", nbucket);
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
}
|
}
|
||||||
unsigned const m = elf_hash(name) % nbucket;
|
if (nbucket) {
|
||||||
unsigned si;
|
unsigned const m = elf_hash(name) % nbucket;
|
||||||
for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) {
|
unsigned si;
|
||||||
char const *const p= get_dynsym_name(si, (unsigned)-1);
|
for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) {
|
||||||
if (0==strcmp(name, p)) {
|
char const *const p= get_dynsym_name(si, (unsigned)-1);
|
||||||
return &dynsym[si];
|
if (0==strcmp(name, p)) {
|
||||||
|
return &dynsym[si];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5756,8 +5757,7 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
|
|||||||
unsigned const *const bitmask = &gashtab[4];
|
unsigned const *const bitmask = &gashtab[4];
|
||||||
unsigned const *const buckets = &bitmask[n_bitmask];
|
unsigned const *const buckets = &bitmask[n_bitmask];
|
||||||
unsigned const *const hasharr = &buckets[n_bucket];
|
unsigned const *const hasharr = &buckets[n_bucket];
|
||||||
if (!n_bucket
|
if ((void const *)&file_image[file_size] <= (void const *)hasharr) {
|
||||||
|| (void const *)&file_image[file_size] <= (void const *)hasharr) {
|
|
||||||
char msg[80]; snprintf(msg, sizeof(msg),
|
char msg[80]; snprintf(msg, sizeof(msg),
|
||||||
"bad n_bucket %#x\n", n_bucket);
|
"bad n_bucket %#x\n", n_bucket);
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
@ -5769,33 +5769,33 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
|
|||||||
"bad n_bitmask %#x\n", n_bitmask);
|
"bad n_bitmask %#x\n", n_bitmask);
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
}
|
}
|
||||||
|
if (n_bucket) {
|
||||||
|
unsigned const h = gnu_hash(name);
|
||||||
|
unsigned const hbit1 = 037& h;
|
||||||
|
unsigned const hbit2 = 037& (h>>gnu_shift);
|
||||||
|
unsigned const w = get_te32(&bitmask[(n_bitmask -1) & (h>>5)]);
|
||||||
|
|
||||||
unsigned const h = gnu_hash(name);
|
if (1& (w>>hbit1) & (w>>hbit2)) {
|
||||||
unsigned const hbit1 = 037& h;
|
unsigned bucket = get_te32(&buckets[h % n_bucket]);
|
||||||
unsigned const hbit2 = 037& (h>>gnu_shift);
|
if (n_bucket <= bucket) {
|
||||||
unsigned const w = get_te32(&bitmask[(n_bitmask -1) & (h>>5)]);
|
char msg[90]; snprintf(msg, sizeof(msg),
|
||||||
|
"bad DT_GNU_HASH n_bucket{%#x} <= buckets[%d]{%#x}\n",
|
||||||
if (1& (w>>hbit1) & (w>>hbit2)) {
|
n_bucket, h % n_bucket, bucket);
|
||||||
unsigned bucket = get_te32(&buckets[h % n_bucket]);
|
throwCantPack(msg);
|
||||||
if (n_bucket <= bucket) {
|
}
|
||||||
char msg[90]; snprintf(msg, sizeof(msg),
|
if (0!=bucket) {
|
||||||
"bad DT_GNU_HASH n_bucket{%#x} <= buckets[%d]{%#x}\n",
|
Elf32_Sym const *dsp = &dynsym[bucket];
|
||||||
n_bucket, h % n_bucket, bucket);
|
unsigned const *hp = &hasharr[bucket - symbias];
|
||||||
throwCantPack(msg);
|
do if (0==((h ^ get_te32(hp))>>1)) {
|
||||||
}
|
unsigned st_name = get_te32(&dsp->st_name);
|
||||||
if (0!=bucket) {
|
char const *const p = get_str_name(st_name, (unsigned)-1);
|
||||||
Elf32_Sym const *dsp = &dynsym[bucket];
|
if (0==strcmp(name, p)) {
|
||||||
unsigned const *hp = &hasharr[bucket - symbias];
|
return dsp;
|
||||||
|
}
|
||||||
do if (0==((h ^ get_te32(hp))>>1)) {
|
} while (++dsp,
|
||||||
unsigned st_name = get_te32(&dsp->st_name);
|
(char const *)hp < (char const *)&file_image[file_size]
|
||||||
char const *const p = get_str_name(st_name, (unsigned)-1);
|
&& 0==(1u& get_te32(hp++)));
|
||||||
if (0==strcmp(name, p)) {
|
}
|
||||||
return dsp;
|
|
||||||
}
|
|
||||||
} while (++dsp,
|
|
||||||
(char const *)hp < (char const *)&file_image[file_size]
|
|
||||||
&& 0==(1u& get_te32(hp++)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5803,6 +5803,7 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
|
|||||||
// (1==n_bucket && 0==buckets[0] && 1==n_bitmask && 0==bitmask[0])
|
// (1==n_bucket && 0==buckets[0] && 1==n_bitmask && 0==bitmask[0])
|
||||||
// to minimize space in DT_GNU_HASH. This causes the fancy lookup to fail.
|
// to minimize space in DT_GNU_HASH. This causes the fancy lookup to fail.
|
||||||
// Is a fallback to linear seach assumed?
|
// Is a fallback to linear seach assumed?
|
||||||
|
// 2022-03-12 Some Rust programs have 0==n_bucket.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -5813,19 +5814,20 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const
|
|||||||
unsigned const nbucket = get_te32(&hashtab[0]);
|
unsigned const nbucket = get_te32(&hashtab[0]);
|
||||||
unsigned const *const buckets = &hashtab[2];
|
unsigned const *const buckets = &hashtab[2];
|
||||||
unsigned const *const chains = &buckets[nbucket];
|
unsigned const *const chains = &buckets[nbucket];
|
||||||
if (!nbucket
|
if ((unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image))
|
||||||
|| (unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image))
|
|
||||||
<= sizeof(unsigned)*nbucket ) {
|
<= sizeof(unsigned)*nbucket ) {
|
||||||
char msg[80]; snprintf(msg, sizeof(msg),
|
char msg[80]; snprintf(msg, sizeof(msg),
|
||||||
"bad nbucket %#x\n", nbucket);
|
"bad nbucket %#x\n", nbucket);
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
}
|
}
|
||||||
unsigned const m = elf_hash(name) % nbucket;
|
if (nbucket) { // -rust-musl can have "empty" hashtab
|
||||||
unsigned si;
|
unsigned const m = elf_hash(name) % nbucket;
|
||||||
for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) {
|
unsigned si;
|
||||||
char const *const p= get_dynsym_name(si, (unsigned)-1);
|
for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) {
|
||||||
if (0==strcmp(name, p)) {
|
char const *const p= get_dynsym_name(si, (unsigned)-1);
|
||||||
return &dynsym[si];
|
if (0==strcmp(name, p)) {
|
||||||
|
return &dynsym[si];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5837,8 +5839,8 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const
|
|||||||
upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4];
|
upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4];
|
||||||
unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask];
|
unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask];
|
||||||
unsigned const *const hasharr = &buckets[n_bucket];
|
unsigned const *const hasharr = &buckets[n_bucket];
|
||||||
if (!n_bucket
|
|
||||||
|| (void const *)&file_image[file_size] <= (void const *)hasharr) {
|
if ((void const *)&file_image[file_size] <= (void const *)hasharr) {
|
||||||
char msg[80]; snprintf(msg, sizeof(msg),
|
char msg[80]; snprintf(msg, sizeof(msg),
|
||||||
"bad n_bucket %#x\n", n_bucket);
|
"bad n_bucket %#x\n", n_bucket);
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
@ -5850,33 +5852,32 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const
|
|||||||
"bad n_bitmask %#x\n", n_bitmask);
|
"bad n_bitmask %#x\n", n_bitmask);
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
}
|
}
|
||||||
|
if (n_bucket) { // -rust-musl can have "empty" gashtab
|
||||||
unsigned const h = gnu_hash(name);
|
unsigned const h = gnu_hash(name);
|
||||||
unsigned const hbit1 = 077& h;
|
unsigned const hbit1 = 077& h;
|
||||||
unsigned const hbit2 = 077& (h>>gnu_shift);
|
unsigned const hbit2 = 077& (h>>gnu_shift);
|
||||||
upx_uint64_t const w = get_te64(&bitmask[(n_bitmask -1) & (h>>6)]);
|
upx_uint64_t const w = get_te64(&bitmask[(n_bitmask -1) & (h>>6)]);
|
||||||
|
if (1& (w>>hbit1) & (w>>hbit2)) {
|
||||||
if (1& (w>>hbit1) & (w>>hbit2)) {
|
unsigned bucket = get_te32(&buckets[h % n_bucket]);
|
||||||
unsigned bucket = get_te32(&buckets[h % n_bucket]);
|
if (n_bucket <= bucket) {
|
||||||
if (n_bucket <= bucket) {
|
char msg[90]; snprintf(msg, sizeof(msg),
|
||||||
char msg[90]; snprintf(msg, sizeof(msg),
|
"bad DT_GNU_HASH n_bucket{%#x} <= buckets[%d]{%#x}\n",
|
||||||
"bad DT_GNU_HASH n_bucket{%#x} <= buckets[%d]{%#x}\n",
|
n_bucket, h % n_bucket, bucket);
|
||||||
n_bucket, h % n_bucket, bucket);
|
throwCantPack(msg);
|
||||||
throwCantPack(msg);
|
}
|
||||||
}
|
if (0!=bucket) {
|
||||||
if (0!=bucket) {
|
Elf64_Sym const *dsp = &dynsym[bucket];
|
||||||
Elf64_Sym const *dsp = &dynsym[bucket];
|
unsigned const *hp = &hasharr[bucket - symbias];
|
||||||
unsigned const *hp = &hasharr[bucket - symbias];
|
do if (0==((h ^ get_te32(hp))>>1)) {
|
||||||
|
unsigned st_name = get_te32(&dsp->st_name);
|
||||||
do if (0==((h ^ get_te32(hp))>>1)) {
|
char const *const p = get_str_name(st_name, (unsigned)-1);
|
||||||
unsigned st_name = get_te32(&dsp->st_name);
|
if (0==strcmp(name, p)) {
|
||||||
char const *const p = get_str_name(st_name, (unsigned)-1);
|
return dsp;
|
||||||
if (0==strcmp(name, p)) {
|
}
|
||||||
return dsp;
|
} while (++dsp,
|
||||||
}
|
(char const *)hp < (char const *)&file_image[file_size]
|
||||||
} while (++dsp,
|
&& 0==(1u& get_te32(hp++)));
|
||||||
(char const *)hp < (char const *)&file_image[file_size]
|
}
|
||||||
&& 0==(1u& get_te32(hp++)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5884,6 +5885,7 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const
|
|||||||
// (1==n_bucket && 0==buckets[0] && 1==n_bitmask && 0==bitmask[0])
|
// (1==n_bucket && 0==buckets[0] && 1==n_bitmask && 0==bitmask[0])
|
||||||
// to minimize space in DT_GNU_HASH. This causes the fancy lookup to fail.
|
// to minimize space in DT_GNU_HASH. This causes the fancy lookup to fail.
|
||||||
// Is a fallback to linear seach assumed?
|
// Is a fallback to linear seach assumed?
|
||||||
|
// 2022-03-12 Some Rust programs have 0==n_bucket.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user