=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/kdump/kdump.c,v retrieving revision 1.92 retrieving revision 1.93 diff -u -r1.92 -r1.93 --- src/usr.bin/kdump/kdump.c 2014/12/08 21:23:44 1.92 +++ src/usr.bin/kdump/kdump.c 2014/12/09 00:46:43 1.93 @@ -1,4 +1,4 @@ -/* $OpenBSD: kdump.c,v 1.92 2014/12/08 21:23:44 guenther Exp $ */ +/* $OpenBSD: kdump.c,v 1.93 2014/12/09 00:46:43 jsg Exp $ */ /*- * Copyright (c) 1988, 1993 @@ -142,7 +142,7 @@ static void ktrgenio(struct ktr_genio *, size_t); static void ktrnamei(const char *, size_t); static void ktrpsig(struct ktr_psig *); -static void ktrsyscall(struct ktr_syscall *); +static void ktrsyscall(struct ktr_syscall *, size_t); static const char *kresolvsysctl(int, int *, int); static void ktrsysret(struct ktr_sysret *); static void ktruser(struct ktr_user *, size_t); @@ -262,7 +262,7 @@ current = findemul(ktr_header.ktr_pid); switch (ktr_header.ktr_type) { case KTR_SYSCALL: - ktrsyscall((struct ktr_syscall *)m); + ktrsyscall((struct ktr_syscall *)m, ktrlen); break; case KTR_SYSRET: ktrsysret((struct ktr_sysret *)m); @@ -878,12 +878,16 @@ static void -ktrsyscall(struct ktr_syscall *ktr) +ktrsyscall(struct ktr_syscall *ktr, size_t ktrlen) { register_t *ap; int narg; char sep; + if (ktr->ktr_argsize > ktrlen) + errx(1, "syscall argument length %d > ktr header length %zu", + ktr->ktr_argsize, ktrlen); + narg = ktr->ktr_argsize / sizeof(register_t); sep = '\0'; @@ -906,6 +910,8 @@ n = ap[1]; if (n > CTL_MAXNAME) n = CTL_MAXNAME; + if (n < 0) + errx(1, "invalid sysctl length %d", n); np = top = (int *)(ap + 6); for (i = 0; n--; np++, i++) { if (sep) @@ -941,7 +947,7 @@ } nonnative: - while (narg) { + while (narg > 0) { if (sep) putchar(sep); if (decimal) @@ -1250,8 +1256,13 @@ ktrgenio(struct ktr_genio *ktr, size_t len) { unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio); - size_t datalen = len - sizeof(struct ktr_genio); + size_t datalen; + if (len < sizeof(struct ktr_genio)) + errx(1, "invalid ktr genio length %zu", len); + + datalen = len - sizeof(struct ktr_genio); + printf("fd %d %s %zu bytes\n", ktr->ktr_fd, ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen); if (maxdata == 0) @@ -1266,7 +1277,7 @@ static void ktrpsig(struct ktr_psig *psig) { - (void)printf("SIG%s ", sys_signame[psig->signo]); + signame(psig->signo); if (psig->action == SIG_DFL) (void)printf("SIG_DFL"); else { @@ -1328,6 +1339,8 @@ static void ktruser(struct ktr_user *usr, size_t len) { + if (len < sizeof(struct ktr_user)) + errx(1, "invalid ktr user length %zu", len); len -= sizeof(struct ktr_user); printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id); printf(" %zu bytes\n", len);