Fix multiple segfaults in the AppleTalk printer when a packet structs
extend past the actual captured length.
Also add "const" to a struct cast to maintain consistency.
Other issues to be addressed in future patches.
Index: print-atalk.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-atalk.c,v
retrieving revision 1.29
diff -u -p -r1.29 print-atalk.c
--- print-atalk.c 21 Aug 2015 02:07:32 -0000 1.29
+++ print-atalk.c 8 Nov 2015 21:05:17 -0000
@@ -98,7 +98,7 @@ atalk_print(register const u_char *bp, u
register const struct atDDP *dp;
u_short snet;
- if (length < ddpSize) {
+ if (length < ddpSize || !TTEST2(bp[0], sizeof(struct atDDP))) {
(void)printf(" [|ddp %d]", length);
return;
}
@@ -128,13 +128,18 @@ atalk_print_llap(register const u_char *
register const struct atShortDDP *sdp;
u_short snet;
- lp = (struct LAP *)bp;
+ if (length < sizeof(struct LAP) || !TTEST2(bp[0], sizeof(struct LAP))) {
+ printf(" [|llap %u]", length);
+ return;
+ }
+ lp = (const struct LAP *)bp;
bp += sizeof(*lp);
length -= sizeof(*lp);
switch (lp->type) {
case lapShortDDP:
- if (length < ddpSSize) {
+ if (length < ddpSSize ||
+ !TTEST2(bp[0], sizeof(struct atShortDDP))) {
(void)printf(" [|sddp %d]", length);
return;
}
@@ -149,7 +154,7 @@ atalk_print_llap(register const u_char *
break;
case lapDDP:
- if (length < ddpSize) {
+ if (length < ddpSize || !TTEST2(bp[0], sizeof(struct atDDP))) {
(void)printf(" [|ddp %d]", length);
return;
}
@@ -187,6 +192,11 @@ aarp_print(register const u_char *bp, u_
#define AT(member)
ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3])
printf("aarp ");
+ if (length < sizeof(struct aarp) ||
+ !TTEST2(bp[0], sizeof(struct aarp))) {
+ printf(" [|aarp %u]", length);
+ return;
+ }
ap = (const struct aarp *)bp;
if (ntohs(ap->htype) == 1 && ntohs(ap->ptype) == ETHERTYPE_ATALK &&
ap->halen == 6 && ap->palen == 4 )