Commit d499a04b authored by Daniel McArdle's avatar Daniel McArdle Committed by Commit Bot

Add bounds check before casting Netlink data in AddressTrackerLinux

Bug: 1016184
Change-Id: I794d668dbfe12cc713e435ddc086490787627afb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1894462Reviewed-by: default avatarPaul Jensen <pauljensen@chromium.org>
Commit-Queue: Dan McArdle <dmcardle@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712173}
parent 109ac8e3
...@@ -111,6 +111,16 @@ bool GetAddress(const struct nlmsghdr* header, ...@@ -111,6 +111,16 @@ bool GetAddress(const struct nlmsghdr* header,
return true; return true;
} }
// SafelyCastNetlinkMsgData<T> performs a bounds check before casting |header|'s
// data to a |T*|. When the bounds check fails, returns nullptr.
template <typename T>
T* SafelyCastNetlinkMsgData(const struct nlmsghdr* header, int length) {
DCHECK(NLMSG_OK(header, static_cast<__u32>(length)));
if (length <= 0 || static_cast<size_t>(length) < NLMSG_HDRLEN + sizeof(T))
return nullptr;
return reinterpret_cast<T*>(NLMSG_DATA(header));
}
} // namespace } // namespace
// static // static
...@@ -347,14 +357,18 @@ void AddressTrackerLinux::HandleMessage(const char* buffer, ...@@ -347,14 +357,18 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
return; return;
case NLMSG_ERROR: { case NLMSG_ERROR: {
const struct nlmsgerr* msg = const struct nlmsgerr* msg =
reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(header)); SafelyCastNetlinkMsgData<struct nlmsgerr>(header, length);
if (msg == nullptr)
return;
LOG(ERROR) << "Unexpected netlink error " << msg->error << "."; LOG(ERROR) << "Unexpected netlink error " << msg->error << ".";
} return; } return;
case RTM_NEWADDR: { case RTM_NEWADDR: {
IPAddress address; IPAddress address;
bool really_deprecated; bool really_deprecated;
struct ifaddrmsg* msg = struct ifaddrmsg* msg =
reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(header)); SafelyCastNetlinkMsgData<struct ifaddrmsg>(header, length);
if (msg == nullptr)
return;
if (IsInterfaceIgnored(msg->ifa_index)) if (IsInterfaceIgnored(msg->ifa_index))
break; break;
if (GetAddress(header, length, &address, &really_deprecated)) { if (GetAddress(header, length, &address, &really_deprecated)) {
...@@ -383,7 +397,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer, ...@@ -383,7 +397,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
case RTM_DELADDR: { case RTM_DELADDR: {
IPAddress address; IPAddress address;
const struct ifaddrmsg* msg = const struct ifaddrmsg* msg =
reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(header)); SafelyCastNetlinkMsgData<struct ifaddrmsg>(header, length);
if (msg == nullptr)
return;
if (IsInterfaceIgnored(msg->ifa_index)) if (IsInterfaceIgnored(msg->ifa_index))
break; break;
if (GetAddress(header, length, &address, nullptr)) { if (GetAddress(header, length, &address, nullptr)) {
...@@ -394,7 +410,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer, ...@@ -394,7 +410,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
} break; } break;
case RTM_NEWLINK: { case RTM_NEWLINK: {
const struct ifinfomsg* msg = const struct ifinfomsg* msg =
reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); SafelyCastNetlinkMsgData<struct ifinfomsg>(header, length);
if (msg == nullptr)
return;
if (IsInterfaceIgnored(msg->ifi_index)) if (IsInterfaceIgnored(msg->ifi_index))
break; break;
if (IgnoreWirelessChange(msg, IFLA_PAYLOAD(header))) { if (IgnoreWirelessChange(msg, IFLA_PAYLOAD(header))) {
...@@ -420,7 +438,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer, ...@@ -420,7 +438,9 @@ void AddressTrackerLinux::HandleMessage(const char* buffer,
} break; } break;
case RTM_DELLINK: { case RTM_DELLINK: {
const struct ifinfomsg* msg = const struct ifinfomsg* msg =
reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); SafelyCastNetlinkMsgData<struct ifinfomsg>(header, length);
if (msg == nullptr)
return;
if (IsInterfaceIgnored(msg->ifi_index)) if (IsInterfaceIgnored(msg->ifi_index))
break; break;
AddressTrackerAutoLock lock(*this, online_links_lock_); AddressTrackerAutoLock lock(*this, online_links_lock_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment