Date: Sat, 23 Oct 2010 16:36:55 GMT From: Alexey Illarionov <littlesavage@rambler.ru> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/151664: [PATCH] sbin/route/route.c: Incorrect array bounds checking Message-ID: <201010231636.o9NGatRM030686@www.freebsd.org> Resent-Message-ID: <201010231640.o9NGe51D074537@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 151664 >Category: bin >Synopsis: [PATCH] sbin/route/route.c: Incorrect array bounds checking >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Oct 23 16:40:04 UTC 2010 >Closed-Date: >Last-Modified: >Originator: Alexey Illarionov >Release: 8.1-STABLE >Organization: >Environment: 8.1-STABLE >Description: sbin/route/route.c have incorrect bounds checking of msgtypes[] in print_rtmsg(): char *msgtypes[] = { "", ... 0 }; void print_rtmsg(rtm, msglen) { .. if (msgtypes[rtm->rtm_type] != NULL) (void)printf("%s: ", msgtypes[rtm->rtm_type]); .. } There is also no checks for received message length (msglen) there. >How-To-Repeat: Run `route monitor` and send invalid message to PF_ROUTE socket: $ route monitor & [1] 13682 $ perl -MSocket -e 'socket(SOCK, PF_ROUTE, SOCK_RAW, 0); syswrite(SOCK, pack("Scc",4,5,0xa0));' got message of size 4 on Sat Oct 23 20:26:51 2010 [1]+ Segmentation fault: 11 route monitor >Fix: Patch attached with submission follows: --- route.c.orig 2010-10-23 19:33:31.560869646 +0400 +++ route.c 2010-10-23 20:28:18.947314302 +0400 @@ -1303,7 +1303,7 @@ "RTM_NEWMADDR: new multicast group membership on iface", "RTM_DELMADDR: multicast group membership removed from iface", "RTM_IFANNOUNCE: interface arrival/departure", - 0, + "RTM_IEEE80211: IEEE80211 wireless event" }; char metricnames[] = @@ -1341,7 +1341,7 @@ rtm->rtm_version); return; } - if (msgtypes[rtm->rtm_type] != NULL) + if (rtm->rtm_type < sizeof(msgtypes)/sizeof(msgtypes[0])) (void)printf("%s: ", msgtypes[rtm->rtm_type]); else (void)printf("#%d: ", rtm->rtm_type); @@ -1349,6 +1349,10 @@ switch (rtm->rtm_type) { case RTM_IFINFO: ifm = (struct if_msghdr *)rtm; + if (msglen < sizeof(struct if_msghdr)) { + printf("invalid\n"); + break; + } (void) printf("if# %d, ", ifm->ifm_index); switch (ifm->ifm_data.ifi_link_state) { case LINK_STATE_DOWN: @@ -1368,6 +1372,10 @@ case RTM_NEWADDR: case RTM_DELADDR: ifam = (struct ifa_msghdr *)rtm; + if (msglen < sizeof(struct ifa_msghdr)) { + printf("invalid\n"); + break; + } (void) printf("metric %d, flags:", ifam->ifam_metric); bprintf(stdout, ifam->ifam_flags, routeflags); pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs); @@ -1376,11 +1384,19 @@ case RTM_NEWMADDR: case RTM_DELMADDR: ifmam = (struct ifma_msghdr *)rtm; + if (msglen < sizeof(struct ifma_msghdr)) { + printf("invalid\n"); + break; + } pmsg_addrs((char *)(ifmam + 1), ifmam->ifmam_addrs); break; #endif case RTM_IFANNOUNCE: ifan = (struct if_announcemsghdr *)rtm; + if (msglen < sizeof(struct if_announcemsghdr)) { + printf("invalid\n"); + break; + } (void) printf("if# %d, what: ", ifan->ifan_index); switch (ifan->ifan_what) { case IFAN_ARRIVAL: @@ -1397,6 +1413,10 @@ break; default: + if (msglen < sizeof(struct if_msghdr)){ + printf("invalid\n"); + break; + } (void) printf("pid: %ld, seq %d, errno %d, flags:", (long)rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno); bprintf(stdout, rtm->rtm_flags, routeflags); >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010231636.o9NGatRM030686>