From 3991ca5657269fbfc38f01ad757f57dd8a461f37 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Sun, 10 May 2020 05:53:10 +0000 Subject: [PATCH] Parse IFA_F_* values above 0x80. In RTM_NEWADDR messages, the first 8 flags are reported in the ifa_flags field in struct ifaddrmsg, but flags above 0x80 are reported in the IFA_FLAGS attribute. NetlinkEvent currently only looks at ifa_flags, so it cannot see higher-value flags such as IFA_F_STABLE_PRIVACY. Fix this by parsing the IFA_FLAGS attribute. Bug: 155005831 Test: makes new test in aosp/1295495 pass Original-Change: https://android-review.googlesource.com/1295670 Merged-In: I723f1106cbcea2186fc6452305942a0f8301fd2a Change-Id: I723f1106cbcea2186fc6452305942a0f8301fd2a --- libsysutils/src/NetlinkEvent.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp index 5efe03f13..3340f8a45 100644 --- a/libsysutils/src/NetlinkEvent.cpp +++ b/libsysutils/src/NetlinkEvent.cpp @@ -180,6 +180,7 @@ bool NetlinkEvent::parseIfAddrMessage(const struct nlmsghdr *nh) { struct ifa_cacheinfo *cacheinfo = nullptr; char addrstr[INET6_ADDRSTRLEN] = ""; char ifname[IFNAMSIZ] = ""; + uint32_t flags = 0; if (!checkRtNetlinkLength(nh, sizeof(*ifaddr))) return false; @@ -230,6 +231,10 @@ bool NetlinkEvent::parseIfAddrMessage(const struct nlmsghdr *nh) { SLOGD("Unknown ifindex %d in %s", ifaddr->ifa_index, msgtype); } + // First 8 bits of flags. In practice will always be overridden by the IFA_FLAGS below, + // because that always appears after IFA_ADDRESS. But just in case, support both orders. + flags = (flags & 0xffffff00) | ifaddr->ifa_flags; + } else if (rta->rta_type == IFA_CACHEINFO) { // Address lifetime information. if (maybeLogDuplicateAttribute(cacheinfo, "IFA_CACHEINFO", msgtype)) @@ -242,6 +247,10 @@ bool NetlinkEvent::parseIfAddrMessage(const struct nlmsghdr *nh) { } cacheinfo = (struct ifa_cacheinfo *) RTA_DATA(rta); + + } else if (rta->rta_type == IFA_FLAGS) { + // In practice IFA_FLAGS is always after IFA_ADDRESS, so this will overwrite the flags. + flags = *(uint32_t*)RTA_DATA(rta); } } @@ -256,7 +265,7 @@ bool NetlinkEvent::parseIfAddrMessage(const struct nlmsghdr *nh) { mSubsystem = strdup("net"); asprintf(&mParams[0], "ADDRESS=%s/%d", addrstr, ifaddr->ifa_prefixlen); asprintf(&mParams[1], "INTERFACE=%s", ifname); - asprintf(&mParams[2], "FLAGS=%u", ifaddr->ifa_flags); + asprintf(&mParams[2], "FLAGS=%u", flags); asprintf(&mParams[3], "SCOPE=%u", ifaddr->ifa_scope); asprintf(&mParams[4], "IFINDEX=%u", ifaddr->ifa_index);