macvlan: require init-userns CAP_NET_ADMIN to raise bc_queue_len

IFLA_MACVLAN_BC_QUEUE_LEN accepts any u32 and becomes
port->bc_queue_len_used, the only bound on port->bc_queue. rtnetlink checks
CAP_NET_ADMIN against the target netns only, so a user who unshares a
user+net namespace, creates a veth and puts a macvlan on it can set the
backlog to 0xffffffff and flood broadcast frames until the host dies:

  Out of memory: Killed process 141 (su) UID:0
  Kernel panic - not syncing: System is deadlocked on memory
  Call Trace:
   vpanic (kernel/panic.c:650)
   panic (kernel/panic.c:787)
   out_of_memory (mm/oom_kill.c:1166)
   __alloc_frozen_pages_noprof (mm/page_alloc.c:4914)
   alloc_pages_mpol (mm/mempolicy.c:2490)
   folio_alloc_noprof (mm/mempolicy.c:2591)
   filemap_fault (mm/filemap.c:3565)

A fixed upper bound does not work. Deployments carrying 600-800 real-time
audio streams run bc_queue_len=100000, and no constant serves both cases:
the queue counts skbs, not bytes, and the frame size is attacker-chosen too
(up to ETH_MAX_MTU on a veth the caller creates).

Gate the elevated range on CAP_NET_ADMIN in the initial user namespace
instead. A backlog of that size is a host-wide tuning decision, and an
unprivileged owner of a namespace it created itself should not be able to
make it; privileged configurations keep working unchanged..

Cc: stable+noautosel@kernel.org # local DoS by userns are a dime a dozen
Reported-by: AutonomousCodeSecurity@microsoft.com
Link: https://lore.kernel.org/r/20260706212556.3199234-1-xmei5@asu.edu
Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Link: https://patch.msgid.link/20260729200621.2521588-1-xmei5@asu.edu
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Xiang Mei (Microsoft)
2026-07-29 20:06:21 +00:00
committed by Jakub Kicinski
parent 95a390ce6a
commit 1a930d5734

View File

@@ -1339,6 +1339,15 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
if (!data)
return 0;
if (data[IFLA_MACVLAN_BC_QUEUE_LEN] &&
nla_get_u32(data[IFLA_MACVLAN_BC_QUEUE_LEN]) >
MACVLAN_DEFAULT_BC_QUEUE_LEN &&
!capable(CAP_NET_ADMIN)) {
NL_SET_ERR_MSG_ATTR(extack, data[IFLA_MACVLAN_BC_QUEUE_LEN],
"bc_queue_len above the default requires CAP_NET_ADMIN in the initial user namespace");
return -EPERM;
}
if (data[IFLA_MACVLAN_FLAGS] &&
nla_get_u16(data[IFLA_MACVLAN_FLAGS]) & ~(MACVLAN_FLAG_NOPROMISC |
MACVLAN_FLAG_NODST))