Fix ifaddrs error handling.
An NLMSG_ERROR packet includes an errno value that we should use. Also report
failures to create a socket immediately, rather than falling through to the
send and reporting EBADF.
Bug: http://b/32145516
Bug: http://b/31038971
Test: bionic ifaddr tests on ryu (with broken kernel) and flounder
Change-Id: I84c480c5b75077eb90d40426a9d66d7bffbd3d51
diff --git a/libc/bionic/bionic_netlink.cpp b/libc/bionic/bionic_netlink.cpp
index 19ca88d..f2449dc 100644
--- a/libc/bionic/bionic_netlink.cpp
+++ b/libc/bionic/bionic_netlink.cpp
@@ -61,6 +61,7 @@
// Did we open a netlink socket yet?
if (fd_ == -1) {
fd_ = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
+ if (fd_ == -1) return false;
}
// Construct and send the message.
@@ -83,7 +84,11 @@
nlmsghdr* hdr = reinterpret_cast<nlmsghdr*>(data_);
for (; NLMSG_OK(hdr, static_cast<size_t>(bytes_read)); hdr = NLMSG_NEXT(hdr, bytes_read)) {
if (hdr->nlmsg_type == NLMSG_DONE) return true;
- if (hdr->nlmsg_type == NLMSG_ERROR) return false;
+ if (hdr->nlmsg_type == NLMSG_ERROR) {
+ nlmsgerr* err = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(hdr));
+ errno = (hdr->nlmsg_len >= NLMSG_LENGTH(sizeof(nlmsgerr))) ? -err->error : EIO;
+ return false;
+ }
callback(context, hdr);
}
}