aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-09-15 23:52:13 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-09-15 23:52:13 +0000
commit7bd9103237bea4ed0b156e2ebec6e5a574abdd90 (patch)
tree3b2683ba5691ba3c45cb2e12421650638f0584f9
parent60ba335dbf1e481894a92beebb82cfe64f5c316c (diff)
parentbe4e18d619edcc8f09534a4ec84428cf23b09a13 (diff)
downloadbionic-android11-mainline-sparse-2021-jan-release.tar.gz
Change-Id: Iaf330670367c7004be4cf5c1201774de9c97030c
-rw-r--r--libc/bionic/ifaddrs.cpp32
-rw-r--r--libc/dns/resolv/res_send.c4
-rw-r--r--tests/cfi_test.cpp3
3 files changed, 33 insertions, 6 deletions
diff --git a/libc/bionic/ifaddrs.cpp b/libc/bionic/ifaddrs.cpp
index e89b0bf11..153633353 100644
--- a/libc/bionic/ifaddrs.cpp
+++ b/libc/bionic/ifaddrs.cpp
@@ -28,6 +28,7 @@
#include <ifaddrs.h>
+#include <async_safe/log.h>
#include <cutils/misc.h> // FIRST_APPLICATION_UID
#include <errno.h>
#include <linux/if_packet.h>
@@ -205,12 +206,12 @@ static void __getifaddrs_callback(void* context, nlmsghdr* hdr) {
new_addr->interface_index = static_cast<int>(msg->ifa_index);
// If this is a known interface, copy what we already know.
+ // If we don't know about this interface yet, we try to resolve the name and flags using ioctl
+ // calls during postprocessing.
if (known_addr != nullptr) {
strcpy(new_addr->name, known_addr->name);
new_addr->ifa.ifa_name = new_addr->name;
new_addr->ifa.ifa_flags = known_addr->ifa.ifa_flags;
- } else {
- new_addr->ifa.ifa_flags = msg->ifa_flags;
}
// Go through the various bits of information and find the name, address
@@ -271,10 +272,34 @@ static void resolve_or_remove_nameless_interfaces(ifaddrs** list) {
} else {
prev_addr = addr;
}
+
addr = reinterpret_cast<ifaddrs_storage*>(next_addr);
}
}
+static void get_interface_flags_via_ioctl(ifaddrs** list) {
+ ScopedFd s(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+ if (s.get() == -1) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC) failed in ifaddrs: %s",
+ strerror(errno));
+ return;
+ }
+
+ for (ifaddrs_storage* addr = reinterpret_cast<ifaddrs_storage*>(*list); addr != nullptr;
+ addr = reinterpret_cast<ifaddrs_storage*>(addr->ifa.ifa_next)) {
+ ifreq ifr = {};
+ strlcpy(ifr.ifr_name, addr->ifa.ifa_name, sizeof(ifr.ifr_name));
+ if (ioctl(s.get(), SIOCGIFFLAGS, &ifr) != -1) {
+ addr->ifa.ifa_flags = ifr.ifr_flags;
+ } else {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "ioctl(SIOCGIFFLAGS) for \"%s\" failed in ifaddrs: %s",
+ addr->ifa.ifa_name, strerror(errno));
+ }
+ }
+}
+
int getifaddrs(ifaddrs** out) {
// We construct the result directly into `out`, so terminate the list.
*out = nullptr;
@@ -303,6 +328,9 @@ int getifaddrs(ifaddrs** out) {
// If we weren't able to depend on GETLINK messages, it's possible some
// interfaces never got their name set. Resolve them using if_indextoname or remove them.
resolve_or_remove_nameless_interfaces(out);
+ // Similarly, without GETLINK messages, interfaces will not have their flags set.
+ // Resolve them using the SIOCGIFFLAGS ioctl call.
+ get_interface_flags_via_ioctl(out);
}
return 0;
diff --git a/libc/dns/resolv/res_send.c b/libc/dns/resolv/res_send.c
index a645a6b4a..fa81e6dc5 100644
--- a/libc/dns/resolv/res_send.c
+++ b/libc/dns/resolv/res_send.c
@@ -948,6 +948,8 @@ send_vc(res_state statp, struct __res_params* params,
else
break;
}
+ // return size should never exceed container size
+ resplen = anssiz;
}
/*
* If the calling applicating has bailed out of
@@ -960,7 +962,7 @@ send_vc(res_state statp, struct __res_params* params,
DprintQ((statp->options & RES_DEBUG) ||
(statp->pfcode & RES_PRF_REPLY),
(stdout, ";; old answer (unexpected):\n"),
- ans, (resplen > anssiz) ? anssiz: resplen);
+ ans, resplen);
goto read_len;
}
diff --git a/tests/cfi_test.cpp b/tests/cfi_test.cpp
index 792f917b2..e0ae3afc7 100644
--- a/tests/cfi_test.cpp
+++ b/tests/cfi_test.cpp
@@ -95,9 +95,6 @@ TEST(cfi_test, basic) {
EXPECT_EQ(get_global_address(), get_last_address());
EXPECT_EQ(c, get_count());
- // CFI check for a stack address. This is always invalid and gets the process killed.
- EXPECT_DEATH(__cfi_slowpath(45, reinterpret_cast<void*>(&c)), "");
-
// CFI check for a heap address.
// It's possible that this allocation could wind up in the same CFI granule as
// an unchecked library, which means the below might not crash. To force a