From nobody Sun Jun 14 02:45:12 2026 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) (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 EEC0E3D7D8D for ; Mon, 4 May 2026 12:58:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777899482; cv=none; b=FEWcq6F+ZG8+40J9JsbBuNNRr3pSXVItelLPAvgrDl6fCX1bxSfyizF4bvPJYc6MJyQf6tCkBzmrKqpv5pgcI8C6R7uWNhkhNdKodaj39t/tfjsRheRIVmjN4hU/x/c1mLw7AuBRQsOdDApqy2ZQy4kzBu9nTJPVIdLZ+br0F+E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777899482; c=relaxed/simple; bh=+mo3C6yzqMAksWubJQ/UbNn3zX4fALJsxYwaY5clI+g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZtnYGRkcD6Dl2bNQQJN9sWhJJuPLuRoWPhxtjauwRsDVb1EOc9UgKzrWtJVv4z0I6jllWxVgU/Fv7d4CcCkKE5Z46e9qdpWPQXoNmtyz3kHxKfeOtcSY4Hs9RgHvIXmo6MhUEwx9J/kSBIGCPNolE3Ayx9IHlJJNtFRwTINlSHc= 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=Tco+vu+D; arc=none smtp.client-ip=209.85.210.175 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="Tco+vu+D" Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-8296d553142so2916615b3a.3 for ; Mon, 04 May 2026 05:58:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777899480; x=1778504280; 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=Tco+vu+Dd8nXNOaE+Q7GVZyumHmnCH0aEB9fv6qw681xU2lrvO5cE+lA1gLbQkMovb 0DWovdsNDGVgBEPo/oD/hM14EMeOzWWDufokidUzP0tiOkuLtrTHStQMioPNuSVjLmN5 l7YEcaKwlWrgW02N0N/gtWsy/R8bD7DsnzBjn4PzngLfbXgbN0bJimYE+uIFsdkb9kX8 onN8Bq/QdFvv9ZplEGoIzfu6M+voeKB3idgiCVYuCM17BRhQ8rA4iTgSdjRcxrDT6doG pi5+Wb6PfSDF3f42YqpbBG8BHhovLjs6pz7Z62yDYsCxKx21u4Jp0ziIKtSs8/lZwLDm oBfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777899480; x=1778504280; 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=K8GCdk9DgVaiUObu/0apePsL1DSBRdxJPweBmFunU/+Cjekjs5pmUJiLYyRLAIJ5GB R6hyJjQCN9utfFL2MwUA6v7f9S5S3WwA4/XFTKSilJyNYfyvUqRekqlDmmqXNhSunDj9 skbhqnbza0Vhy0aHBPTGXrFEwt52xsyYy6kdfVT0VlCWQB7F1r7LghSfoKWfwgyo8sx9 wkGocA/ZbpqeOBKXuigermj1irJXTa+4EZ9ozL+72Rh5i+WLs4N7+VyVSirhseWbAUdn PTBINz/jfCrmsxSEHGzlk0rxvvzFAWyTw/hci+H5s+QnorfUdo2Lmp1n2UShCPbGLP07 Y1Xw== X-Forwarded-Encrypted: i=1; AFNElJ93CmmIi7JD0La+AopN/deT5qTxybkOucW8gq20IuYNJb75uFShJkZun0TqfDSuIsHli9hdxm7R4gp0FfY=@vger.kernel.org X-Gm-Message-State: AOJu0Yz5ctEn0TGeO2X/G6a54je2qOlQpZGjZTp4hIqdqzf0MHynd248 1vc7MEaR8yUA6nOF+CCOB/0GYYuKq10TseCFs3QHhaDb0Nri1rk6/V+G X-Gm-Gg: AeBDieur0WbQ8DLWf263AJTlh2cUsaGuMJFutKd7kPSEbm8KkU4D7rKkbeQkQpzeB6v 2XuD6BbR2O26w7/MGCDP62z/K9W40YCBL1fr26JIKFTGCMLXj7NKmjlehEwm3YEFS+aPcnvT00r MmLajhKQl6mZPcoNh2M/S+i8BQifgWmzvQU85siLc0SxoJCLclIkwcUoMxfjkRWGIqwA7UkWGMc XhVL5Op8oG2/gtVi6+S3RKGxNZPdcoH0zpAippse3X6rV1ikIDgYFMDoIB0XB7HyOYYdAtFsJSR Nhdxu56UjlnrfXzk6In36Kr5oF4dR62to5GIGseOBC6e5MC65fUNlQ76WaF3S5flFECy5bwTqW/ vLZ5kDxU57hI/nughIcYB7XBBgz0RhGyV1A6ke+d7omqT3W4Coa4VowqFdjkOyzQaKsmEr0Sz9I riZVG3Tp1pVKSpIEv5txc8ydZXx566P+5jbJqy9OLDMCC5HYKFdtvvleprNt0U/hlWDRM= X-Received: by 2002:a05:6a00:460e:b0:838:6d43:9486 with SMTP id d2e1a72fcca58-8386d43a2bcmr1362596b3a.10.1777899480120; Mon, 04 May 2026 05:58:00 -0700 (PDT) Received: from csl-conti-dell7858.ntu.edu.sg ([155.69.195.57]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-835158aeebesm10748864b3a.21.2026.05.04.05.57.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 May 2026 05:57:59 -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 1/2] wifi: nl80211: require CAP_NET_ADMIN over the target netns in SET_WIPHY_NETNS Date: Mon, 4 May 2026 20:57:52 +0800 Message-Id: <20260504125753.1154601-2-maoyi.xie@ntu.edu.sg> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260504125753.1154601-1-maoyi.xie@ntu.edu.sg> References: <20260504125753.1154601-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:12 2026 Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) (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 F25DC3D8907 for ; Mon, 4 May 2026 12:58:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777899484; cv=none; b=HBN3bI9QkqX9jCZILCw7fkRevJL52LkO+Iu3eS2qMnl9gdObtuvGO8h55rWwjEc+tX4XEzlnh8ZzgrNInrZV+DmEPR7wXzMVE5xTnioBDKa1b3t1HyqJrDDiYGN27AKwmfW136o2PJZxMKh3lltjelQejQ5nHD6jc7ek+A2YBMo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777899484; c=relaxed/simple; bh=WGxwPMj0Jvf62Qf3yIRmxkG+rH8nxvYdAc3vMvAc7YU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qGf91f7+dZ4Hmwwoz/vshTmxczURF16ZJq0I47mOLdgxr3DxUu2A4SDujGhw0lD39KWh1R2YdrG+Han2zi3PnMUHwbuRKpSgHaiOwPcPIf2Pjc4p6BjistPmViPs8qo7QZHd4VzzlNRhFWfUkx5rKgCQfpRbui1XUAMY2r1EHqg= 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=CkgJhMCK; arc=none smtp.client-ip=209.85.210.172 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="CkgJhMCK" Received: by mail-pf1-f172.google.com with SMTP id d2e1a72fcca58-82fbdd60b64so2904374b3a.3 for ; Mon, 04 May 2026 05:58:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777899482; x=1778504282; 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=4UnTF1dih5K5oi/fx4+6E+Hsrs0XoMIeCSQF+wiUqTc=; b=CkgJhMCK+rjEZhU7f3CSJEnhPuWiCdCKtHUryJzcW/C0BBDrXeRkHuFHgoOFiAX2qW mY2CHzS/cD3F8/OQl267Icr7fIt0Fly+vP+O6XA0zYlNHHhITXAPF/Zx8LYCxCrVlRIU AOyeg2jO8QSLGY0lI9SK+oFoQ8falTR/JTnKK7QJw1jVQDA/AEW3wzhQOWrP+dmfAs8O rxUIDI1KSlPeIoX0USvSacTxnwRlzzKHexdXkYfnso58pFoNBkYj8Agn1Gs4qWCS2sbI actKjiMtcEPgBacMmLfvb/KalKmzkf1ORL6/OSuyqGlmZiq5Dv6MynbiY0VrfpINH3Fk 7LTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777899482; x=1778504282; 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=4UnTF1dih5K5oi/fx4+6E+Hsrs0XoMIeCSQF+wiUqTc=; b=UQ2rlGWNQzrt0wEVXVskYQ2lxYYR7oOkyLIZwjU8mxbbIvAYSSxqHF0P0vT/DVprPm 4VIexvguwheBzOjDoDMvu/rN8CcDetqoU4OjsrKZhfM2Xuuo5BT1OW8I72oswnVFNUhO PdH20vGJOg5keAap8bxcLLou7XI8Hxgup4N6PolNlxZBQvCaIOmgNTsSFDU8u7LC65WO eegQBgE5Ij/qzSYJmQGk/+4dNSGzAQ+bTW+kHF8nIgn6Dip6gvtG3TpP4yF9qVSoNFIz +1P+fHcQKQC/6usAvYi48BsvIdhe1Q60fE4C9xKikhfAA4cmBnulqG81B1brRpbRZGPw Q7Ug== X-Forwarded-Encrypted: i=1; AFNElJ/IdjXdKTLrh19EEgfgZXoB93NsgXtFsOeiOGDe/rpq2HHTymIqw8dgZWGhyfG2HycNxcHZ8FEj7nu9fVk=@vger.kernel.org X-Gm-Message-State: AOJu0YzXMCObkReW2j43y1CyadY+27NpF3VnJpQPriIg63wS0xh3+I3O Fxn4czoqh9Upl4G42Q/xjdKFeO+t36U02JCHArS8z9Kh9mojpUSU+vC9 X-Gm-Gg: AeBDietqhlkeUTTlOXU9/5xQDxBFCNSztI8rU3gCvmnZtT0eVZfqFzhZkvi5MuEXE76 g9vO1X/NjaBxQT4yb8rTGF6zMFsAnUBXDQ7tpE1nh9xj5iY8jyVMCGpBEUEtk1WS2Vf2x4C8hg2 g/EoICNmwlNSfSiUAZMQG70+QWbmUZZFBIGKHpGpr52kJLtkKmt9pAkcIruFZd4NAazILrHzISh cS7XbU0Gonv7wKyf4cEtImgRIE70pz0dICLICThxpbeRi5O95T5hLfzuZBHfv/fHsAkRtTWFGpZ X8ug70s4plpxjnvfoXYl/3zjd13Sg18iZr9HeacJBrWVEkcMCgtRole7+2JoP15sfUX4DNcPBE6 wb/Aj0qqsItr7vbjgAVDGLy4iMGLya5ATjaqMarHczvCpJslvYQrYhtCEX5ji/ldYbRUYsfm0f7 ZrSyxtfKGBeKyG98xnB0J/MwT1yK/2rU6IZI7BmKBFRHOBAp566VHq8goW X-Received: by 2002:a05:6a00:3a15:b0:82f:390a:69c7 with SMTP id d2e1a72fcca58-8352d2b58ccmr8968444b3a.33.1777899482140; Mon, 04 May 2026 05:58:02 -0700 (PDT) Received: from csl-conti-dell7858.ntu.edu.sg ([155.69.195.57]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-835158aeebesm10748864b3a.21.2026.05.04.05.58.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 May 2026 05:58:01 -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 2/2] wifi: nl80211: re-check wiphy netns in nl80211_prepare_wdev_dump() continuation Date: Mon, 4 May 2026 20:57:53 +0800 Message-Id: <20260504125753.1154601-3-maoyi.xie@ntu.edu.sg> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260504125753.1154601-1-maoyi.xie@ntu.edu.sg> References: <20260504125753.1154601-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 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index db546dd93..61b9e5eb0 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1276,6 +1276,18 @@ 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. Other + * dump paths in this file (nl80211_dump_wiphy() and friends) + * already do this check on every iteration. + */ + 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