Merge #32 `Fix for systems with page size larger than 4k`
commit
fc64fd023d
@ -0,0 +1,86 @@
|
||||
From 96ee2a8e20bb7a7c4fb19e27dc31ff5c6a472849 Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Gonzalez <rymg19@gmail.com>
|
||||
Date: Mon, 06 Mar 2023 20:22:25 -0600
|
||||
Subject: [PATCH] AddressTrackerLinux: Increase the message buffer size
|
||||
|
||||
On non-4k-page systems, the message sizes may be too large to fit into
|
||||
the buffer, resulting in MSG_TRUNC. Instead of using the fixed 4kb size,
|
||||
follow the kernel documentation guidelines as to how large the buffer
|
||||
should be.
|
||||
|
||||
Originally found by Asahi Lina:
|
||||
|
||||
https://vt.social/@lina/109976892758680822
|
||||
|
||||
Bug: None
|
||||
Change-Id: I4790435190167a706fa7490ab57706db1f4a6120
|
||||
---
|
||||
|
||||
diff --git a/net/base/address_tracker_linux.cc b/net/base/address_tracker_linux.cc
|
||||
index 4976cae..f1a1fff 100644
|
||||
--- a/net/base/address_tracker_linux.cc
|
||||
+++ b/net/base/address_tracker_linux.cc
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "base/files/scoped_file.h"
|
||||
#include "base/functional/callback_helpers.h"
|
||||
#include "base/logging.h"
|
||||
+#include "base/memory/page_size.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
#include "base/task/current_thread.h"
|
||||
#include "base/threading/scoped_blocking_call.h"
|
||||
@@ -323,8 +324,30 @@
|
||||
*address_changed = false;
|
||||
*link_changed = false;
|
||||
*tunnel_changed = false;
|
||||
- char buffer[4096];
|
||||
bool first_loop = true;
|
||||
+
|
||||
+ // Varying sources have different opinions regarding the buffer size needed
|
||||
+ // for netlink messages to avoid truncation:
|
||||
+ // - The official documentation on netlink says messages are generally 8kb
|
||||
+ // or the system page size, whichever is *larger*:
|
||||
+ // https://www.kernel.org/doc/html/v6.2/userspace-api/netlink/intro.html#buffer-sizing
|
||||
+ // - The kernel headers would imply that messages are generally the system
|
||||
+ // page size or 8kb, whichever is *smaller*:
|
||||
+ // https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/linux/netlink.h?h=v6.2.2#n226
|
||||
+ // (libmnl follows this.)
|
||||
+ // - The netlink(7) man page's example always uses a fixed size 8kb buffer:
|
||||
+ // https://man7.org/linux/man-pages/man7/netlink.7.html
|
||||
+ // Here, we follow the guidelines in the documentation, for two primary
|
||||
+ // reasons:
|
||||
+ // - Erring on the side of a larger size is the safer way to go to avoid
|
||||
+ // MSG_TRUNC.
|
||||
+ // - Since this is heap-allocated anyway, there's no risk to the stack by
|
||||
+ // using the larger size.
|
||||
+
|
||||
+ constexpr size_t kMinNetlinkBufferSize = 8 * 1024;
|
||||
+ std::vector<char> buffer(
|
||||
+ std::max(base::GetPageSize(), kMinNetlinkBufferSize));
|
||||
+
|
||||
{
|
||||
absl::optional<base::ScopedBlockingCall> blocking_call;
|
||||
if (tracking_) {
|
||||
@@ -334,9 +357,10 @@
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
- int rv = HANDLE_EINTR(recv(netlink_fd_.get(), buffer, sizeof(buffer),
|
||||
- // Block the first time through loop.
|
||||
- first_loop ? 0 : MSG_DONTWAIT));
|
||||
+ int rv =
|
||||
+ HANDLE_EINTR(recv(netlink_fd_.get(), buffer.data(), buffer.size(),
|
||||
+ // Block the first time through loop.
|
||||
+ first_loop ? 0 : MSG_DONTWAIT));
|
||||
first_loop = false;
|
||||
if (rv == 0) {
|
||||
LOG(ERROR) << "Unexpected shutdown of NETLINK socket.";
|
||||
@@ -348,7 +372,8 @@
|
||||
PLOG(ERROR) << "Failed to recv from netlink socket";
|
||||
return;
|
||||
}
|
||||
- HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed);
|
||||
+ HandleMessage(buffer.data(), rv, address_changed, link_changed,
|
||||
+ tunnel_changed);
|
||||
}
|
||||
}
|
||||
if (*link_changed || *address_changed)
|
Loading…
Reference in new issue