diff options
author | Patrick Kelsey <pkelsey@FreeBSD.org> | 2017-04-16 19:17:10 +0000 |
---|---|---|
committer | Patrick Kelsey <pkelsey@FreeBSD.org> | 2017-04-16 19:17:10 +0000 |
commit | 2f8c6c0a587f7b9276ffeb1713f063026cfc9093 (patch) | |
tree | dc6ff3b2220f19ee8bc75d89795c29e154342212 /sbin | |
parent | c48dc2a193b9befceda8dfc6f894d73251cc00a4 (diff) | |
download | src-2f8c6c0a587f7b9276ffeb1713f063026cfc9093.tar.gz src-2f8c6c0a587f7b9276ffeb1713f063026cfc9093.zip |
Fix userland tools that don't check the format of routing socket
messages before accessing message fields that may not be present,
removing dead/duplicate/misleading code along the way.
Document the message format for each routing socket message in
route.h.
Fix a bug in usr.bin/netstat introduced in r287351 that resulted in
pointer computation with essentially random 16-bit offsets and
dereferencing of the results.
Reviewed by: ae
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D10330
Notes
Notes:
svn path=/head/; revision=317035
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/route/route.c | 19 | ||||
-rw-r--r-- | sbin/routed/table.c | 9 |
2 files changed, 19 insertions, 9 deletions
diff --git a/sbin/route/route.c b/sbin/route/route.c index 97da81766c79..062fecd3cc3b 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -1497,10 +1497,7 @@ rtmsg(int cmd, int flags, int fib) #define NEXTADDR(w, u) \ if (rtm_addrs & (w)) { \ - l = (((struct sockaddr *)&(u))->sa_len == 0) ? \ - sizeof(long) : \ - 1 + ((((struct sockaddr *)&(u))->sa_len - 1) \ - | (sizeof(long) - 1)); \ + l = SA_SIZE(&(u)); \ memmove(cp, (char *)&(u), l); \ cp += l; \ if (verbose) \ @@ -1564,7 +1561,8 @@ rtmsg(int cmd, int flags, int fib) do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && stop_read == 0 && - (rtm.rtm_seq != rtm_seq || rtm.rtm_pid != pid)); + (rtm.rtm_type != RTM_GET || rtm.rtm_seq != rtm_seq || + rtm.rtm_pid != pid)); if (stop_read != 0) { warnx("read from routing socket timed out"); return (-1); @@ -1706,10 +1704,13 @@ print_rtmsg(struct rt_msghdr *rtm, size_t msglen) break; default: - printf("pid: %ld, seq %d, errno %d, flags:", - (long)rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno); - printb(rtm->rtm_flags, routeflags); - pmsg_common(rtm, msglen); + if (rtm->rtm_type <= RTM_RESOLVE) { + printf("pid: %ld, seq %d, errno %d, flags:", + (long)rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno); + printb(rtm->rtm_flags, routeflags); + pmsg_common(rtm, msglen); + } else + printf("type: %u, len: %zu\n", rtm->rtm_type, msglen); } return; diff --git a/sbin/routed/table.c b/sbin/routed/table.c index ce2c18d392e2..fe719cd31d29 100644 --- a/sbin/routed/table.c +++ b/sbin/routed/table.c @@ -1233,6 +1233,15 @@ read_rt(void) if (m.r.rtm.rtm_type <= RTM_CHANGE) strp += sprintf(strp," from pid %d",m.r.rtm.rtm_pid); + /* + * Only messages that use the struct rt_msghdr format are + * allowed beyond this point. + */ + if (m.r.rtm.rtm_type > RTM_RESOLVE) { + trace_act("ignore %s", str); + continue; + } + rt_xaddrs(&info, m.r.addrs, &m.r.addrs[RTAX_MAX], m.r.rtm.rtm_addrs); |