summaryrefslogtreecommitdiff
path: root/usr.bin/ctfdump
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2017-10-27 09:35:23 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2017-10-27 09:35:23 +0000
commit7031c35900263267e37e1721aae330154f375982 (patch)
treea7422b1a2c4ea914b38867d7f71870c92ee8fb31 /usr.bin/ctfdump
parentebfa3910dd2bfeae0241dc204d646f4cff7be744 (diff)
Prevent out-of-bound with malformed type entry.
Issue found by jsg@ with afl(1).
Diffstat (limited to 'usr.bin/ctfdump')
-rw-r--r--usr.bin/ctfdump/ctfdump.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/usr.bin/ctfdump/ctfdump.c b/usr.bin/ctfdump/ctfdump.c
index 9b9a6981e57..46f69fe7f82 100644
--- a/usr.bin/ctfdump/ctfdump.c
+++ b/usr.bin/ctfdump/ctfdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ctfdump.c,v 1.13 2017/10/27 09:22:20 mpi Exp $ */
+/* $OpenBSD: ctfdump.c,v 1.14 2017/10/27 09:35:22 mpi Exp $ */
/*
* Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
@@ -52,8 +52,8 @@ int isctf(const char *, size_t);
__dead void usage(void);
int ctf_dump(const char *, size_t, uint8_t);
-uint32_t ctf_dump_type(struct ctf_header *, const char *, off_t,
- uint32_t, uint32_t);
+void ctf_dump_type(struct ctf_header *, const char *, off_t,
+ uint32_t, uint32_t *, uint32_t);
const char *ctf_kind2name(uint16_t);
const char *ctf_enc2name(uint16_t);
const char *ctf_fpenc2name(uint16_t);
@@ -381,9 +381,10 @@ ctf_dump(const char *p, size_t size, uint8_t flags)
if (flags & DUMP_TYPE) {
uint32_t idx = 1, offset = cth->cth_typeoff;
+ uint32_t stroff = cth->cth_stroff;
- while (offset < cth->cth_stroff) {
- offset += ctf_dump_type(cth, data, dlen, offset, idx++);
+ while (offset < stroff) {
+ ctf_dump_type(cth, data, dlen, stroff, &offset, idx++);
}
printf("\n");
}
@@ -412,11 +413,11 @@ ctf_dump(const char *p, size_t size, uint8_t flags)
return 0;
}
-uint32_t
+void
ctf_dump_type(struct ctf_header *cth, const char *data, off_t dlen,
- uint32_t offset, uint32_t idx)
+ uint32_t stroff, uint32_t *offset, uint32_t idx)
{
- const char *p = data + offset;
+ const char *p = data + *offset;
const struct ctf_type *ctt = (struct ctf_type *)p;
const struct ctf_array *cta;
uint16_t *argp, i, kind, vlen, root;
@@ -487,6 +488,9 @@ ctf_dump_type(struct ctf_header *cth, const char *data, off_t dlen,
for (i = 0; i < vlen; i++) {
struct ctf_member *ctm;
+ if (toff > (stroff - sizeof(*ctm)))
+ break;
+
ctm = (struct ctf_member *)(p + toff);
toff += sizeof(struct ctf_member);
@@ -499,6 +503,9 @@ ctf_dump_type(struct ctf_header *cth, const char *data, off_t dlen,
for (i = 0; i < vlen; i++) {
struct ctf_lmember *ctlm;
+ if (toff > (stroff - sizeof(*ctlm)))
+ break;
+
ctlm = (struct ctf_lmember *)(p + toff);
toff += sizeof(struct ctf_lmember);
@@ -514,6 +521,9 @@ ctf_dump_type(struct ctf_header *cth, const char *data, off_t dlen,
for (i = 0; i < vlen; i++) {
struct ctf_enum *cte;
+ if (toff > (stroff - sizeof(*cte)))
+ break;
+
cte = (struct ctf_enum *)(p + toff);
toff += sizeof(struct ctf_enum);
@@ -530,12 +540,12 @@ ctf_dump_type(struct ctf_header *cth, const char *data, off_t dlen,
printf(" refers to %u", ctt->ctt_type);
break;
default:
- errx(1, "incorrect type %u at offset %u", kind, offset);
+ errx(1, "incorrect type %u at offset %u", kind, *offset);
}
printf("\n");
- return toff;
+ *offset += toff;
}
const char *