diff options
author | Remi NGUYEN VAN <reminv@google.com> | 2022-06-14 17:05:57 +0900 |
---|---|---|
committer | Remi NGUYEN VAN <reminv@google.com> | 2022-06-14 17:05:57 +0900 |
commit | e5434e1b07089809ca46b65276f8de612f4ba715 (patch) | |
tree | a67be57e21e7e500f3bb60d171921c348bb3933a | |
parent | e9c96727e7e42c0ef6ff8edf79087b81a5fb5082 (diff) | |
download | mdnsresponder-e5434e1b07089809ca46b65276f8de612f4ba715.tar.gz |
Avoid undefined behavior with high interface index
Behavior of bitwise left shift is undefined when the right operator is
greater than the number of bits in the left operand; so the code relied
on undefined behavior when interface indexes were >= 32.
Just use a boolean instead, as the result was only used as a boolean.
Also do not limit reads in if_inet6 to 1 byte for address flags, scope
value, and prefix length, as there is no good reason to do so, and this
is in line with more recent upstream versions and the interface index
read. In practice prefix length, scope value and interface flags should
not be above 255 so this should be a no-op.
Bug: 235797641
Test: atest NsdManagerTest --rerun-until-failure 50
Change-Id: I41fae1900400779cecb715e8cfb1e662b88fd41d
-rw-r--r-- | mDNSPosix/mDNSPosix.c | 22 | ||||
-rwxr-xr-x | mDNSPosix/mDNSUNP.c | 2 |
2 files changed, 10 insertions, 14 deletions
diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c index 8960c93..28f4e06 100644 --- a/mDNSPosix/mDNSPosix.c +++ b/mDNSPosix/mDNSPosix.c @@ -1102,14 +1102,14 @@ mDNSlocal void PrintNetLinkMsg(const struct nlmsghdr *pNLMsg) } #endif -mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) +mDNSlocal mDNSBool ProcessRoutingNotification(int sd) // Read through the messages on sd and if any indicate that any interface records should // be torn down and rebuilt, return affected indices as a bitmask. Otherwise return 0. { ssize_t readCount; char buff[4096]; struct nlmsghdr *pNLMsg = (struct nlmsghdr*) buff; - mDNSu32 result = 0; + mDNSBool result = mDNSfalse; // The structure here is more complex than it really ought to be because, // unfortunately, there's no good way to size a buffer in advance large @@ -1144,10 +1144,9 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) #endif // Process the NetLink message - if (pNLMsg->nlmsg_type == RTM_GETLINK || pNLMsg->nlmsg_type == RTM_NEWLINK) - result |= 1 << ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index; - else if (pNLMsg->nlmsg_type == RTM_DELADDR || pNLMsg->nlmsg_type == RTM_NEWADDR) - result |= 1 << ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index; + if (pNLMsg->nlmsg_type == RTM_GETLINK || pNLMsg->nlmsg_type == RTM_NEWLINK || + pNLMsg->nlmsg_type == RTM_DELADDR || pNLMsg->nlmsg_type == RTM_NEWADDR) + result = mDNStrue; // Advance pNLMsg to the next message in the buffer if ((pNLMsg->nlmsg_flags & NLM_F_MULTI) != 0 && pNLMsg->nlmsg_type != NLMSG_DONE) @@ -1191,14 +1190,14 @@ mDNSlocal void PrintRoutingSocketMsg(const struct ifa_msghdr *pRSMsg) } #endif -mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) +mDNSlocal mDNSBool ProcessRoutingNotification(int sd) // Read through the messages on sd and if any indicate that any interface records should // be torn down and rebuilt, return affected indices as a bitmask. Otherwise return 0. { ssize_t readCount; char buff[4096]; struct ifa_msghdr *pRSMsg = (struct ifa_msghdr*) buff; - mDNSu32 result = 0; + mDNSBool result = mDNSfalse; readCount = read(sd, buff, sizeof buff); if (readCount < (ssize_t) sizeof(struct ifa_msghdr)) @@ -1212,10 +1211,7 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) if (pRSMsg->ifam_type == RTM_NEWADDR || pRSMsg->ifam_type == RTM_DELADDR || pRSMsg->ifam_type == RTM_IFINFO) { - if (pRSMsg->ifam_type == RTM_IFINFO) - result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index; - else - result |= 1 << pRSMsg->ifam_index; + result = mDNStrue; } return result; @@ -1228,7 +1224,7 @@ mDNSlocal void InterfaceChangeCallback(int fd, short filter, void *context) { IfChangeRec *pChgRec = (IfChangeRec*) context; fd_set readFDs; - mDNSu32 changedInterfaces = 0; + mDNSBool changedInterfaces = mDNSfalse; struct timeval zeroTimeout = { 0, 0 }; (void)fd; // Unused diff --git a/mDNSPosix/mDNSUNP.c b/mDNSPosix/mDNSUNP.c index f5d0c52..0e3632b 100755 --- a/mDNSPosix/mDNSUNP.c +++ b/mDNSPosix/mDNSUNP.c @@ -106,7 +106,7 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases) goto gotError; } while (fscanf(fp, - "%4s%4s%4s%4s%4s%4s%4s%4s %x %02x %02x %02x %15s\n", + "%4s%4s%4s%4s%4s%4s%4s%4s %x %x %x %x %15s\n", addr[0],addr[1],addr[2],addr[3], addr[4],addr[5],addr[6],addr[7], &index, &plen, &scope, &flags, ifname) != EOF) { |