diff options
author | midipix <writeonce@midipix.org> | 2024-01-26 00:04:17 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2024-01-26 00:11:36 +0000 |
commit | 3fcae4969c8767d0e3da21b8e75e4c142007d577 (patch) | |
tree | bc837f386bf6358ccc08dbe1c79cce0aeb7f8a5e | |
parent | 380c44ed3129bbeda274350db707c7021e27696d (diff) | |
download | slibtool-3fcae4969c8767d0e3da21b8e75e4c142007d577.tar.bz2 slibtool-3fcae4969c8767d0e3da21b8e75e4c142007d577.tar.xz |
slbt_ar_parse_primary_armap_bsd_64(): more strictly validate the string table.
-rw-r--r-- | src/arbits/slbt_archive_meta.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/arbits/slbt_archive_meta.c b/src/arbits/slbt_archive_meta.c index 1b23c24..9a9540f 100644 --- a/src/arbits/slbt_archive_meta.c +++ b/src/arbits/slbt_archive_meta.c @@ -363,6 +363,7 @@ static int slbt_ar_parse_primary_armap_bsd_64( uint64_t sizeofrefs; uint64_t sizeofstrs; const char * ch; + const char * cap; unsigned char * uch; unsigned char (*mark)[0x08]; @@ -416,20 +417,39 @@ static int slbt_ar_parse_primary_armap_bsd_64( sizeofstrs = u64_lo + (u64_hi << 32); m->symstrs = (const char *)mark; + cap = memberp->ar_object_data; + cap += memberp->ar_object_size; + + if ((cap == m->symstrs) && nsyms) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_AR_INVALID_ARMAP_STRING_TABLE); + if (nsyms && !m->symstrs[0]) return SLBT_CUSTOM_ERROR( dctx, SLBT_ERR_AR_INVALID_ARMAP_STRING_TABLE); - for (ch=&m->symstrs[1],nstrs=0; ch<&m->symstrs[sizeofstrs]; ch++) + for (ch=&m->symstrs[1],nstrs=0; ch<cap; ch++) { + if (!ch[0] && !ch[-1] && (nstrs < nsyms)) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_AR_INVALID_ARMAP_STRING_TABLE); + if (!ch[0] && ch[-1]) nstrs++; + } if (nstrs != nsyms) return SLBT_CUSTOM_ERROR( dctx, SLBT_ERR_AR_INVALID_ARMAP_STRING_TABLE); + if (cap[-1]) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_AR_INVALID_ARMAP_STRING_TABLE); + if (!(m->symstrv = calloc(nsyms + 1,sizeof(const char *)))) return SLBT_SYSTEM_ERROR(dctx,0); |