summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/slibtool/slibtool.h1
-rw-r--r--src/arbits/slbt_archive_meta.c41
2 files changed, 42 insertions, 0 deletions
diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index 8b5429a..2cf7099 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -110,6 +110,7 @@ enum slbt_custom_error {
SLBT_ERR_AR_MISPLACED_ARMAP_MEMBER,
SLBT_ERR_AR_NO_ACTION_SPECIFIED,
SLBT_ERR_AR_NO_INPUT_SPECIFIED,
+ SLBT_ERR_AR_INVALID_ARMAP_NUMBER_OF_SYMS,
SLBT_ERR_AR_INVALID_ARMAP_SIZE_OF_REFS,
SLBT_ERR_AR_INVALID_ARMAP_SIZE_OF_STRS,
SLBT_ERR_AR_INVALID_ARMAP_STRING_TABLE,
diff --git a/src/arbits/slbt_archive_meta.c b/src/arbits/slbt_archive_meta.c
index 5b6874f..0bd0ac7 100644
--- a/src/arbits/slbt_archive_meta.c
+++ b/src/arbits/slbt_archive_meta.c
@@ -439,6 +439,9 @@ static int slbt_ar_parse_primary_armap_sysv_32(
struct ar_meta_member_info * memberp;
struct ar_meta_armap_common_32 *armapref;
uint32_t nsyms;
+ uint32_t nstrs;
+ const char * ch;
+ const char * cap;
unsigned char * uch;
unsigned char (*mark)[0x04];
@@ -455,8 +458,46 @@ static int slbt_ar_parse_primary_armap_sysv_32(
nsyms = (uch[0] << 24) + (uch[1] << 16) + (uch[2] << 8) + uch[3];
mark += nsyms;
+ if (memberp->ar_object_size < (sizeof(*mark) + (nsyms * sizeof(*mark))))
+ return SLBT_CUSTOM_ERROR(
+ dctx,
+ SLBT_ERR_AR_INVALID_ARMAP_NUMBER_OF_SYMS);
+
m->symstrs = (const char *)mark;
+ cap = memberp->ar_object_data;
+ cap += memberp->ar_object_size;
+
+ if (cap == m->symstrs)
+ 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<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);