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 )

Reply via email to