- Fix array bounds checking. [1]
- Add message length checking. PR: 151664 [1] Submitted by: Alexey Illarionov <littlesavage rambler.ru> [1] Reviewed by: yar
This commit is contained in:
parent
e3d05d0821
commit
8c8a1240cf
@ -115,11 +115,11 @@ static void mask_addr(void);
|
||||
static void monitor(void);
|
||||
static const char *netname(struct sockaddr *);
|
||||
static void newroute(int, char **);
|
||||
static void pmsg_addrs(char *, int);
|
||||
static void pmsg_common(struct rt_msghdr *);
|
||||
static void pmsg_addrs(char *, int, size_t);
|
||||
static void pmsg_common(struct rt_msghdr *, size_t);
|
||||
static int prefixlen(const char *);
|
||||
static void print_getmsg(struct rt_msghdr *, int);
|
||||
static void print_rtmsg(struct rt_msghdr *, int);
|
||||
static void print_rtmsg(struct rt_msghdr *, size_t);
|
||||
static const char *routename(struct sockaddr *);
|
||||
static int rtmsg(int, int);
|
||||
static void set_metric(char *, int);
|
||||
@ -1307,7 +1307,6 @@ const char *msgtypes[] = {
|
||||
"RTM_DELMADDR: multicast group membership removed from iface",
|
||||
"RTM_IFANNOUNCE: interface arrival/departure",
|
||||
"RTM_IEEE80211: IEEE 802.11 wireless event",
|
||||
0,
|
||||
};
|
||||
|
||||
char metricnames[] =
|
||||
@ -1325,8 +1324,11 @@ char ifnetflags[] =
|
||||
char addrnames[] =
|
||||
"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
|
||||
|
||||
static const char errfmt[] =
|
||||
"\n%s: truncated route message, only %zu bytes left\n";
|
||||
|
||||
static void
|
||||
print_rtmsg(struct rt_msghdr *rtm, int msglen __unused)
|
||||
print_rtmsg(struct rt_msghdr *rtm, size_t msglen)
|
||||
{
|
||||
struct if_msghdr *ifm;
|
||||
struct ifa_msghdr *ifam;
|
||||
@ -1343,13 +1345,22 @@ print_rtmsg(struct rt_msghdr *rtm, int msglen __unused)
|
||||
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);
|
||||
(void)printf("unknown type %d: ", rtm->rtm_type);
|
||||
(void)printf("len %d, ", rtm->rtm_msglen);
|
||||
|
||||
#define REQUIRE(x) do { \
|
||||
if (msglen < sizeof(x)) \
|
||||
goto badlen; \
|
||||
else \
|
||||
msglen -= sizeof(x); \
|
||||
} while (0)
|
||||
|
||||
switch (rtm->rtm_type) {
|
||||
case RTM_IFINFO:
|
||||
REQUIRE(struct if_msghdr);
|
||||
ifm = (struct if_msghdr *)rtm;
|
||||
(void) printf("if# %d, ", ifm->ifm_index);
|
||||
switch (ifm->ifm_data.ifi_link_state) {
|
||||
@ -1365,23 +1376,26 @@ print_rtmsg(struct rt_msghdr *rtm, int msglen __unused)
|
||||
}
|
||||
(void) printf("link: %s, flags:", state);
|
||||
bprintf(stdout, ifm->ifm_flags, ifnetflags);
|
||||
pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs);
|
||||
pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs, msglen);
|
||||
break;
|
||||
case RTM_NEWADDR:
|
||||
case RTM_DELADDR:
|
||||
REQUIRE(struct ifa_msghdr);
|
||||
ifam = (struct ifa_msghdr *)rtm;
|
||||
(void) printf("metric %d, flags:", ifam->ifam_metric);
|
||||
bprintf(stdout, ifam->ifam_flags, routeflags);
|
||||
pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs);
|
||||
pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs, msglen);
|
||||
break;
|
||||
#ifdef RTM_NEWMADDR
|
||||
case RTM_NEWMADDR:
|
||||
case RTM_DELMADDR:
|
||||
REQUIRE(struct ifma_msghdr);
|
||||
ifmam = (struct ifma_msghdr *)rtm;
|
||||
pmsg_addrs((char *)(ifmam + 1), ifmam->ifmam_addrs);
|
||||
pmsg_addrs((char *)(ifmam + 1), ifmam->ifmam_addrs, msglen);
|
||||
break;
|
||||
#endif
|
||||
case RTM_IFANNOUNCE:
|
||||
REQUIRE(struct if_announcemsghdr);
|
||||
ifan = (struct if_announcemsghdr *)rtm;
|
||||
(void) printf("if# %d, what: ", ifan->ifan_index);
|
||||
switch (ifan->ifan_what) {
|
||||
@ -1402,8 +1416,14 @@ print_rtmsg(struct rt_msghdr *rtm, int msglen __unused)
|
||||
(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);
|
||||
pmsg_common(rtm);
|
||||
pmsg_common(rtm, msglen);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
badlen:
|
||||
(void)printf(errfmt, __func__, msglen);
|
||||
#undef REQUIRE
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1491,7 +1511,7 @@ print_getmsg(struct rt_msghdr *rtm, int msglen)
|
||||
#undef msec
|
||||
#define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD)
|
||||
if (verbose)
|
||||
pmsg_common(rtm);
|
||||
pmsg_common(rtm, msglen);
|
||||
else if (rtm->rtm_addrs &~ RTA_IGN) {
|
||||
(void) printf("sockaddrs: ");
|
||||
bprintf(stdout, rtm->rtm_addrs, addrnames);
|
||||
@ -1501,17 +1521,21 @@ print_getmsg(struct rt_msghdr *rtm, int msglen)
|
||||
}
|
||||
|
||||
static void
|
||||
pmsg_common(struct rt_msghdr *rtm)
|
||||
pmsg_common(struct rt_msghdr *rtm, size_t msglen)
|
||||
{
|
||||
(void) printf("\nlocks: ");
|
||||
bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);
|
||||
(void) printf(" inits: ");
|
||||
bprintf(stdout, rtm->rtm_inits, metricnames);
|
||||
pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs);
|
||||
if (msglen > sizeof(struct rt_msghdr))
|
||||
pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs,
|
||||
msglen - sizeof(struct rt_msghdr));
|
||||
else
|
||||
(void) fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
pmsg_addrs(char *cp, int addrs)
|
||||
pmsg_addrs(char *cp, int addrs, size_t len)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int i;
|
||||
@ -1526,7 +1550,12 @@ pmsg_addrs(char *cp, int addrs)
|
||||
for (i = 1; i != 0; i <<= 1)
|
||||
if (i & addrs) {
|
||||
sa = (struct sockaddr *)cp;
|
||||
if (len == 0 || len < SA_SIZE(sa)) {
|
||||
(void) printf(errfmt, __func__, len);
|
||||
break;
|
||||
}
|
||||
(void) printf(" %s", routename(sa));
|
||||
len -= SA_SIZE(sa);
|
||||
cp += SA_SIZE(sa);
|
||||
}
|
||||
(void) putchar('\n');
|
||||
|
Loading…
Reference in New Issue
Block a user