[PATCH v2 net 2/4] neighbour: Enforce min/max to NDTPA_INTERVAL_PROBE_TIME_MS.
From: Kuniyuki Iwashima <kuniyu@google.com>
Date: 2026-09-08 21:14:24
Subsystem:
documentation, networking [general], networking [ipv4/ipv6], the rest, yaml netlink (ynl) · Maintainers:
Jonathan Corbet, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds, Donald Hunter
NDTPA_INTERVAL_PROBE_TIME_MS sets .type and .min but misses
.validation_type, so no validation is applied:
# ynl --family rt-neigh --do setneightbl \
--json '{"name": "arp_cache", "parms": {"interval-probe-time-ms": 0}}'
# ynl --family rt-neigh --dump getneightbl --output-json | \
jq '.[] | select(.name == "arp_cache" and has("config"))
| .parms["interval-probe-time-ms"]'
0
Moreover, nla_get_msecs() uses msecs_to_jiffies(), and u64 is
silently cast to u32, so a larger value can bypass the min check:
e.g. 4294967296 == 0x100000000
# ynl --family rt-neigh --do setneightbl \
--json '{"name": "arp_cache", "parms": {"interval-probe-time-ms": 4294967296}}'
# ynl --family rt-neigh --dump getneightbl --output-json | \
jq '.[] | select(.name == "arp_cache" and has("config"))
| .parms["interval-probe-time-ms"]'
0
msecs_to_jiffies() returns MAX_JIFFY_OFFSET if the value is
larger than INT_MAX. Also, INT_MAX ms overflows int NEIGH_VAR()
when HZ > 1000 (Alpha, MIPS), and passing a negative integer to
queue_delayed_work(unsigned long delay) causes sign extension,
which wraps around the expiry time to the past, resulting in it
being handled as 0 delay in the timer wheel.
Let's use NLA_POLICY_FULL_RANGE() and limit the max to 1 day.
The same max check is applied to sysctl as well.
Note that this controls the probe interval for NTF_MANAGED
entries, and therefore the max of 1 day is unlikely to break
any deployments.
Fixes: 211da42eaa45 ("net, neigh: introduce interval_probe_time_ms for periodic probe")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
Currently, the sysctl range check is not applied to
interval_probe_time_ms, which needs this fix:
https://lore.kernel.org/linux-fsdevel/20260905233819.1064529-2-kuniyu@google.com/ (local)
Cc: Yuwei Wang <redacted>
v2:
* Clarify the attribute is for NTF_MANAGED
* Update docs, rt-neigh.yaml and ip-sysctl.rst
---
Documentation/netlink/specs/rt-neigh.yaml | 2 ++
Documentation/networking/ip-sysctl.rst | 2 +-
net/core/neighbour.c | 17 +++++++++++++----
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/Documentation/netlink/specs/rt-neigh.yaml b/Documentation/netlink/specs/rt-neigh.yaml
index 0f46ef313590..5ec57d95d7f6 100644
--- a/Documentation/netlink/specs/rt-neigh.yaml
+++ b/Documentation/netlink/specs/rt-neigh.yaml@@ -341,6 +341,8 @@ attribute-sets: - name: interval-probe-time-ms type: u64 + min: 1 + max: 86400000 operations: enum-model: directional
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index 208f46967ee5..b05829e44d8f 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst@@ -248,7 +248,7 @@ neigh/default/unres_qlen - INTEGER neigh/default/interval_probe_time_ms - INTEGER The probe interval for neighbor entries with NTF_MANAGED flag, - the min value is 1. + the min value is 1, and the max value is 86400000 (1 day). Default: 5000
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 49dd7df149ef..0db78a0dfb51 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c@@ -2359,6 +2359,13 @@ static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = { [NDTA_PARMS] = { .type = NLA_NESTED }, }; +#define NTBL_PARM_MS_MAX (24 * 60 * 60 * MSEC_PER_SEC) + +static const struct netlink_range_validation nl_ntbl_parm_ms_range = { + .min = 1, + .max = NTBL_PARM_MS_MAX, +}; + static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { [NDTPA_IFINDEX] = { .type = NLA_U32 }, [NDTPA_QUEUE_LEN] = { .type = NLA_U32 },
@@ -2375,7 +2382,8 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { [NDTPA_ANYCAST_DELAY] = { .type = NLA_U64 }, [NDTPA_PROXY_DELAY] = { .type = NLA_U64 }, [NDTPA_LOCKTIME] = { .type = NLA_U64 }, - [NDTPA_INTERVAL_PROBE_TIME_MS] = { .type = NLA_U64, .min = 1 }, + [NDTPA_INTERVAL_PROBE_TIME_MS] = NLA_POLICY_FULL_RANGE(NLA_U64, + &nl_ntbl_parm_ms_range), }; static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -3672,12 +3680,13 @@ static int neigh_proc_dointvec_ms_jiffies_positive(const struct ctl_table *ctl, void *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table tmp = *ctl; - int ret; + int ret, min, max; - int min = msecs_to_jiffies(1); + min = msecs_to_jiffies(1); + max = msecs_to_jiffies(NTBL_PARM_MS_MAX); tmp.extra1 = &min; - tmp.extra2 = NULL; + tmp.extra2 = &max; ret = proc_dointvec_ms_jiffies_minmax(&tmp, write, buffer, lenp, ppos); neigh_proc_update(ctl, write);
--
2.55.0.979.g7e5102b832-goog