aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemi NGUYEN VAN <reminv@google.com>2022-06-14 17:05:57 +0900
committerRemi NGUYEN VAN <reminv@google.com>2022-06-14 17:05:57 +0900
commite5434e1b07089809ca46b65276f8de612f4ba715 (patch)
treea67be57e21e7e500f3bb60d171921c348bb3933a
parente9c96727e7e42c0ef6ff8edf79087b81a5fb5082 (diff)
downloadmdnsresponder-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.c22
-rwxr-xr-xmDNSPosix/mDNSUNP.c2
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) {