| 0/0 |
2026/05/17 18:09 |
flow |
assessment-security |
58m
Results: map[DenialOfService:false Explanation:Based on the analysis of the bug report and the kernel source code, here is the
assessment of the bug's security impact:
**1. Exploitable: False**
The bug is a `WARN` in `mac80211_hwsim_sta_rc_update` that triggers when a
station's bandwidth (`bw`) is greater than the channel's configured bandwidth
(`confbw`). The `WARN` macro is used as a sanity check. In production builds,
this merely prints a warning message to the kernel log and continues execution.
The `bw` variable is not used for any subsequent logic or memory accesses within
the function, and `mac80211_hwsim` (being a software simulator) does not rely on
this bandwidth value for any critical operations. Therefore, this bug does not
lead to memory corruption, out-of-bounds accesses, or privilege escalation.
**2. Denial Of Service: False**
Since this is a `WARNING` and not a `BUG`, it does not halt the kernel in
production builds (assuming `panic_on_warn` is not set). The violation of the
assumption (station bandwidth > channel bandwidth) is not handled, but it also
has no adverse consequences because the `mac80211_hwsim` driver does not use the
bandwidth value for anything else. It does not cause a system crash, hang,
deadlock, or resource leak. The only consequence is a log message.
**3. Accessible From Unprivileged Processes: False**
The bug is triggered by injecting an 802.11 frame into a simulated radio
configured in OCB (Outside the Context of a BSS) mode. To configure an interface
in OCB mode, the process must send the `NL80211_CMD_JOIN_OCB` netlink command,
which requires the `GENL_UNS_ADMIN_PERM` flag (meaning it requires
`CAP_NET_ADMIN` in the user namespace). Furthermore, injecting frames into the
`mac80211_hwsim` simulator requires registering a socket via
`HWSIM_CMD_REGISTER`, which also requires `CAP_NET_ADMIN`. Thus, an unprivileged
process without namespace access cannot trigger this bug.
**4. Accessible From User Namespaces: True**
Both the `MAC80211_HWSIM` and `nl80211` netlink families have `.netnsok = true`,
meaning they are accessible within network namespaces. The required commands
(`HWSIM_CMD_REGISTER`, `NL80211_CMD_SET_INTERFACE`, `NL80211_CMD_JOIN_OCB`) use
the `GENL_UNS_ADMIN_PERM` flag, which allows execution if the process has
`CAP_NET_ADMIN` in the user namespace that owns the network namespace.
Therefore, an unprivileged user can create a new user/network namespace, gain
the necessary capabilities within it, and trigger the bug.
**5. VM Guest Trigger: False**
While `mac80211_hwsim` does have a virtio driver (`VIRTIO_ID_MAC80211_HWSIM`),
it is a testing tool and not a standard paravirtualized feature exposed to
typical KVM guests by default. The bug is triggered by user-space netlink
interactions within the OS where the simulator is running, not by standard
guest-to-host or host-to-guest VM exits.
**6. VM Host Trigger in The Confidential Computing Context: False**
Even if the host exposes the `mac80211_hwsim` virtio device to a guest, the bug
requires the guest to have already configured a wireless interface in OCB mode
(which is not a default configuration). The host cannot force the guest to
configure OCB mode, so it cannot reliably trigger the bug in the guest.
**7. Ethernet Network Trigger: False**
The bug involves processing 802.11 wireless frames, not Ethernet traffic.
Furthermore, it occurs within a software-simulated radio (`mac80211_hwsim`),
which does not receive traffic from real physical networks.
**8. Other Remote Trigger: False**
Because the bug is located in `mac80211_hwsim.c` (a software simulator for
testing), it cannot be triggered remotely over the air. Real wireless drivers
have their own station addition callbacks and do not use the simulator's code
path.
**9. Peripheral Trigger: False**
The bug is in a virtual/simulated driver, not a driver for a physical peripheral
device. Plugging in a malicious USB or other peripheral will not trigger this
code path.
**10. Malicious Filesystem Trigger: False**
The bug is entirely within the wireless networking subsystem and has no
interaction with filesystem mounting or parsing. Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:true VMGuestTrigger:false VMHostTrigger:false]
|
| 1/1 |
2026/05/17 18:09 |
action |
syz-repro-to-c-repro |
0m
Results: map[SimplifiedCRepro:// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <endian.h>
#include <errno.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/genetlink.h>
#include <linux/if_addr.h>
#include <linux/if_ether.h>
#include <linux/if_link.h>
#include <linux/in6.h>
#include <linux/neighbour.h>
#include <linux/net.h>
#include <linux/netlink.h>
#include <linux/nl80211.h>
#include <linux/rtnetlink.h>
#include <linux/veth.h>
struct nlmsg {
char* pos;
int nesting;
struct nlattr* nested[8];
char buf[4096];
};
static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
const void* data, int size)
{
memset(nlmsg, 0, sizeof(*nlmsg));
struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
hdr->nlmsg_type = typ;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
memcpy(hdr + 1, data, size);
nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
}
static void netlink_attr(struct nlmsg* nlmsg, int typ,
const void* data, int size)
{
struct nlattr* attr = (struct nlattr*)nlmsg->pos;
attr->nla_len = sizeof(*attr) + size;
attr->nla_type = typ;
if (size > 0)
memcpy(attr + 1, data, size);
nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
}
static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
uint16_t reply_type, int* reply_len, bool dofail)
{
if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
exit(1);
struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
struct sockaddr_nl addr;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
if (n != (ssize_t)hdr->nlmsg_len) {
if (dofail)
exit(1);
return -1;
}
n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
if (reply_len)
*reply_len = 0;
if (n < 0) {
if (dofail)
exit(1);
return -1;
}
if (n < (ssize_t)sizeof(struct nlmsghdr)) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
if (hdr->nlmsg_type == NLMSG_DONE)
return 0;
if (reply_len && hdr->nlmsg_type == reply_type) {
*reply_len = n;
return 0;
}
if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
if (hdr->nlmsg_type != NLMSG_ERROR) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
errno = -((struct nlmsgerr*)(hdr + 1))->error;
return -errno;
}
static int netlink_query_family_id(struct nlmsg* nlmsg, int sock, const char* family_name, bool dofail)
{
struct genlmsghdr genlhdr;
memset(&genlhdr, 0, sizeof(genlhdr));
genlhdr.cmd = CTRL_CMD_GETFAMILY;
netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, family_name, strnlen(family_name, GENL_NAMSIZ - 1) + 1);
int n = 0;
int err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n, dofail);
if (err < 0) {
return -1;
}
uint16_t id = 0;
struct nlattr* attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(genlhdr)));
for (; (char*)attr < nlmsg->buf + n; attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
id = *(uint16_t*)(attr + 1);
break;
}
}
if (!id) {
errno = EINVAL;
return -1;
}
recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
return id;
}
#define WIFI_INITIAL_DEVICE_COUNT 2
#define WIFI_MAC_BASE { 0x08, 0x02, 0x11, 0x00, 0x00, 0x00}
#define WIFI_IBSS_BSSID { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50}
#define WIFI_IBSS_SSID { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}
#define WIFI_DEFAULT_FREQUENCY 2412
#define WIFI_DEFAULT_SIGNAL 0
#define WIFI_DEFAULT_RX_RATE 1
#define HWSIM_CMD_REGISTER 1
#define HWSIM_CMD_FRAME 2
#define HWSIM_CMD_NEW_RADIO 4
#define HWSIM_ATTR_SUPPORT_P2P_DEVICE 14
#define HWSIM_ATTR_PERM_ADDR 22
static long syz_genetlink_get_family_id(volatile long name, volatile long sock_arg)
{
int fd = sock_arg;
if (fd < 0) {
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
if (fd == -1) {
return -1;
}
}
struct nlmsg nlmsg_tmp;
int ret = netlink_query_family_id(&nlmsg_tmp, fd, (char*)name, false);
if ((int)sock_arg < 0)
close(fd);
if (ret < 0) {
return -1;
}
return ret;
}
#define HWSIM_ATTR_RX_RATE 5
#define HWSIM_ATTR_SIGNAL 6
#define HWSIM_ATTR_ADDR_RECEIVER 1
#define HWSIM_ATTR_FRAME 3
#define WIFI_MAX_INJECT_LEN 2048
static int hwsim_register_socket(struct nlmsg* nlmsg, int sock, int hwsim_family)
{
struct genlmsghdr genlhdr;
memset(&genlhdr, 0, sizeof(genlhdr));
genlhdr.cmd = HWSIM_CMD_REGISTER;
netlink_init(nlmsg, hwsim_family, 0, &genlhdr, sizeof(genlhdr));
int err = netlink_send_ext(nlmsg, sock, 0, NULL, false);
if (err < 0) {
}
return err;
}
static int hwsim_inject_frame(struct nlmsg* nlmsg, int sock, int hwsim_family, uint8_t* mac_addr, uint8_t* data, int len)
{
struct genlmsghdr genlhdr;
uint32_t rx_rate = WIFI_DEFAULT_RX_RATE;
uint32_t signal = WIFI_DEFAULT_SIGNAL;
memset(&genlhdr, 0, sizeof(genlhdr));
genlhdr.cmd = HWSIM_CMD_FRAME;
netlink_init(nlmsg, hwsim_family, 0, &genlhdr, sizeof(genlhdr));
netlink_attr(nlmsg, HWSIM_ATTR_RX_RATE, &rx_rate, sizeof(rx_rate));
netlink_attr(nlmsg, HWSIM_ATTR_SIGNAL, &signal, sizeof(signal));
netlink_attr(nlmsg, HWSIM_ATTR_ADDR_RECEIVER, mac_addr, ETH_ALEN);
netlink_attr(nlmsg, HWSIM_ATTR_FRAME, data, len);
int err = netlink_send_ext(nlmsg, sock, 0, NULL, false);
if (err < 0) {
}
return err;
}
static long syz_80211_inject_frame(volatile long a0, volatile long a1, volatile long a2)
{
uint8_t* mac_addr = (uint8_t*)a0;
uint8_t* buf = (uint8_t*)a1;
int buf_len = (int)a2;
struct nlmsg tmp_msg;
if (buf_len < 0 || buf_len > WIFI_MAX_INJECT_LEN) {
return -1;
}
int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
if (sock < 0) {
return -1;
}
int hwsim_family_id = netlink_query_family_id(&tmp_msg, sock, "MAC80211_HWSIM", false);
if (hwsim_family_id < 0) {
close(sock);
return -1;
}
int ret = hwsim_register_socket(&tmp_msg, sock, hwsim_family_id);
if (ret < 0) {
close(sock);
return -1;
}
ret = hwsim_inject_frame(&tmp_msg, sock, hwsim_family_id, mac_addr, buf, buf_len);
close(sock);
if (ret < 0) {
return -1;
}
return 0;
}
uint64_t r[4] = {0xffffffffffffffff, 0x0, 0xffffffffffffffff, 0x0};
int main(void)
{
syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
const char* reason;
(void)reason;
intptr_t res = 0;
if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
// socket$nl_generic arguments: [
// domain: const = 0x10 (8 bytes)
// type: const = 0x3 (8 bytes)
// proto: const = 0x10 (4 bytes)
// ]
// returns sock_nl_generic
res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0x10);
if (res != -1)
r[0] = res;
// ioctl$sock_SIOCGIFINDEX_80211 arguments: [
// fd: sock (resource)
// cmd: const = 0x8933 (4 bytes)
// arg: ptr[out, ifreq_dev_t[nl80211_devnames, nl80211_ifindex]] {
// ifreq_dev_t[nl80211_devnames, nl80211_ifindex] {
// ifr_ifrn: buffer: {77 6c 61 6e 31 00 00 00 00 00 00 00 00 00 00 00} (length 0x10)
// elem: nl80211_ifindex (resource)
// pad = 0x0 (20 bytes)
// }
// }
// ]
memcpy((void*)0x200000000100, "wlan1\000\000\000\000\000\000\000\000\000\000\000", 16);
res = syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x8933, /*arg=*/0x200000000100ul);
if (res != -1)
r[1] = *(uint32_t*)0x200000000110;
// socket$nl_generic arguments: [
// domain: const = 0x10 (8 bytes)
// type: const = 0x3 (8 bytes)
// proto: const = 0x10 (4 bytes)
// ]
// returns sock_nl_generic
res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0x10);
if (res != -1)
r[2] = res;
// syz_genetlink_get_family_id$nl80211 arguments: [
// name: ptr[in, buffer] {
// buffer: {6e 6c 38 30 32 31 31 00} (length 0x8)
// }
// fd: sock_nl_generic (resource)
// ]
// returns nl80211_family_id
memcpy((void*)0x200000000200, "nl80211\000", 8);
res = -1;
res = syz_genetlink_get_family_id(/*name=*/0x200000000200, /*fd=*/-1);
if (res != -1)
r[3] = res;
// sendmsg$NL80211_CMD_SET_INTERFACE arguments: [
// fd: sock_nl_generic (resource)
// msg: ptr[in, msghdr_netlink[netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]]] {
// msghdr_netlink[netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]] {
// addr: nil
// addrlen: len = 0x0 (4 bytes)
// pad = 0x0 (4 bytes)
// vec: ptr[in, iovec[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]]] {
// iovec[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]] {
// addr: ptr[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]] {
// netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface] {
// len: len = 0x24 (4 bytes)
// type: nl80211_family_id (resource)
// flags: netlink_msg_flags = 0x5 (2 bytes)
// seq: int32 = 0x0 (4 bytes)
// pid: int32 = 0x0 (4 bytes)
// payload: msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload] {
// genl_hdr: genlmsghdr_t[NL80211_CMD_SET_INTERFACE] {
// cmd: const = 0x6 (1 bytes)
// version: const = 0x0 (1 bytes)
// reserved: const = 0x0 (2 bytes)
// }
// payload: nl80211_wdev_payload {
// NL80211_ATTR_IFINDEX: union optional[nlattr[NL80211_ATTR_IFINDEX, nl80211_ifindex]] {
// val: nlattr_t[const[NL80211_ATTR_IFINDEX, int16], nl80211_ifindex] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x3 (2 bytes)
// payload: nl80211_ifindex (resource)
// size: buffer: {} (length 0x0)
// }
// }
// NL80211_ATTR_WDEV: union optional[nlattr[NL80211_ATTR_WDEV, nl80211_wdev]] {
// void: buffer: {} (length 0x0)
// }
// }
// }
// attrs: array[nl80211_policy$set_interface] {
// union nl80211_policy$set_interface {
// NL80211_ATTR_IFTYPE: nlattr_t[const[NL80211_ATTR_IFTYPE, int16], flags[nl80211_iftype, int32]] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x5 (2 bytes)
// payload: nl80211_iftype = 0xb (4 bytes)
// size: buffer: {} (length 0x0)
// }
// }
// }
// }
// }
// len: len = 0x24 (8 bytes)
// }
// }
// vlen: const = 0x1 (8 bytes)
// ctrl: const = 0x0 (8 bytes)
// ctrllen: const = 0x0 (8 bytes)
// f: send_flags = 0x400c000 (4 bytes)
// pad = 0x0 (4 bytes)
// }
// }
// f: send_flags = 0x0 (8 bytes)
// ]
*(uint64_t*)0x200000000340 = 0;
*(uint32_t*)0x200000000348 = 0;
*(uint64_t*)0x200000000350 = 0x200000000300;
*(uint64_t*)0x200000000300 = 0x200000000000;
*(uint32_t*)0x200000000000 = 0x24;
*(uint16_t*)0x200000000004 = r[3];
*(uint16_t*)0x200000000006 = 5;
*(uint32_t*)0x200000000008 = 0;
*(uint32_t*)0x20000000000c = 0;
*(uint8_t*)0x200000000010 = 6;
*(uint8_t*)0x200000000011 = 0;
*(uint16_t*)0x200000000012 = 0;
*(uint16_t*)0x200000000014 = 8;
*(uint16_t*)0x200000000016 = 3;
*(uint32_t*)0x200000000018 = r[1];
*(uint16_t*)0x20000000001c = 8;
*(uint16_t*)0x20000000001e = 5;
*(uint32_t*)0x200000000020 = 0xb;
*(uint64_t*)0x200000000308 = 0x24;
*(uint64_t*)0x200000000358 = 1;
*(uint64_t*)0x200000000360 = 0;
*(uint64_t*)0x200000000368 = 0;
*(uint32_t*)0x200000000370 = 0x400c000;
syscall(__NR_sendmsg, /*fd=*/r[2], /*msg=*/0x200000000340ul, /*f=*/0ul);
// sendmsg$NL80211_CMD_JOIN_OCB arguments: [
// fd: sock_nl_generic (resource)
// msg: ptr[in, msghdr_netlink[netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]]] {
// msghdr_netlink[netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]] {
// addr: nil
// addrlen: len = 0x0 (4 bytes)
// pad = 0x0 (4 bytes)
// vec: ptr[in, iovec[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]]] {
// iovec[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]] {
// addr: ptr[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]] {
// netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params] {
// len: len = 0x2c (4 bytes)
// type: nl80211_family_id (resource)
// flags: netlink_msg_flags = 0x1 (2 bytes)
// seq: int32 = 0x70bd28 (4 bytes)
// pid: int32 = 0x25dfdbff (4 bytes)
// payload: msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload] {
// genl_hdr: genlmsghdr_t[NL80211_CMD_JOIN_OCB] {
// cmd: const = 0x6c (1 bytes)
// version: const = 0x0 (1 bytes)
// reserved: const = 0x0 (2 bytes)
// }
// payload: nl80211_wdev_payload {
// NL80211_ATTR_IFINDEX: union optional[nlattr[NL80211_ATTR_IFINDEX, nl80211_ifindex]] {
// val: nlattr_t[const[NL80211_ATTR_IFINDEX, int16], nl80211_ifindex] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x3 (2 bytes)
// payload: nl80211_ifindex (resource)
// size: buffer: {} (length 0x0)
// }
// }
// NL80211_ATTR_WDEV: union optional[nlattr[NL80211_ATTR_WDEV, nl80211_wdev]] {
// void: buffer: {} (length 0x0)
// }
// }
// }
// attrs: array[nl80211_policy$chandef_params] {
// union nl80211_policy$chandef_params {
// NL80211_ATTR_WIPHY_FREQ: nlattr_t[const[NL80211_ATTR_WIPHY_FREQ, int16], ieee80211_frequency_mhz[int32]] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x26 (2 bytes)
// payload: union ieee80211_frequency_mhz[int32] {
// default: const = 0x96c (4 bytes)
// }
// size: buffer: {} (length 0x0)
// }
// }
// union nl80211_policy$chandef_params {
// NL80211_ATTR_CHANNEL_WIDTH: nlattr_t[const[NL80211_ATTR_CHANNEL_WIDTH, int16], flags[nl80211_channel_widths, int32]] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x9f (2 bytes)
// payload: nl80211_channel_widths = 0x7 (4 bytes)
// size: buffer: {} (length 0x0)
// }
// }
// }
// }
// }
// len: len = 0x2c (8 bytes)
// }
// }
// vlen: const = 0x1 (8 bytes)
// ctrl: const = 0x0 (8 bytes)
// ctrllen: const = 0x0 (8 bytes)
// f: send_flags = 0x24004015 (4 bytes)
// pad = 0x0 (4 bytes)
// }
// }
// f: send_flags = 0x448d0 (8 bytes)
// ]
*(uint64_t*)0x200000000240 = 0;
*(uint32_t*)0x200000000248 = 0;
*(uint64_t*)0x200000000250 = 0x200000000200;
*(uint64_t*)0x200000000200 = 0x200000000800;
*(uint32_t*)0x200000000800 = 0x2c;
*(uint16_t*)0x200000000804 = r[3];
*(uint16_t*)0x200000000806 = 1;
*(uint32_t*)0x200000000808 = 0x70bd28;
*(uint32_t*)0x20000000080c = 0x25dfdbff;
*(uint8_t*)0x200000000810 = 0x6c;
*(uint8_t*)0x200000000811 = 0;
*(uint16_t*)0x200000000812 = 0;
*(uint16_t*)0x200000000814 = 8;
*(uint16_t*)0x200000000816 = 3;
*(uint32_t*)0x200000000818 = r[1];
*(uint16_t*)0x20000000081c = 8;
*(uint16_t*)0x20000000081e = 0x26;
*(uint32_t*)0x200000000820 = 0x96c;
*(uint16_t*)0x200000000824 = 8;
*(uint16_t*)0x200000000826 = 0x9f;
*(uint32_t*)0x200000000828 = 7;
*(uint64_t*)0x200000000208 = 0x2c;
*(uint64_t*)0x200000000258 = 1;
*(uint64_t*)0x200000000260 = 0;
*(uint64_t*)0x200000000268 = 0;
*(uint32_t*)0x200000000270 = 0x24004015;
syscall(__NR_sendmsg, /*fd=*/r[0], /*msg=*/0x200000000240ul, /*f=MSG_BATCH|MSG_PROBE|MSG_NOSIGNAL|MSG_EOR|MSG_DONTWAIT|MSG_CONFIRM*/0x448d0ul);
// syz_80211_inject_frame arguments: [
// mac_addr: ptr[in, ieee80211_mac_addr] {
// union ieee80211_mac_addr {
// device_b: ieee80211_fixed_mac_addr[const[0x1, int8]] {
// byte0: const = 0x8 (1 bytes)
// byte1: const = 0x2 (1 bytes)
// byte2: const = 0x11 (1 bytes)
// byte3: const = 0x0 (1 bytes)
// byte4: const = 0x0 (1 bytes)
// byte5: const = 0x1 (1 bytes)
// }
// }
// }
// buf: ptr[inout, array[ANYUNION]] {
// array[ANYUNION] {
// union ANYUNION {
// ANYBLOB: buffer: {88 a8 00 60 37 12 00 08 02 11 00 00 00 ff ff ff ff ff ff ff ff ff} (length 0x16)
// }
// }
// }
// buf_len: len = 0x1e (8 bytes)
// ]
*(uint8_t*)0x200000000280 = 8;
*(uint8_t*)0x200000000281 = 2;
*(uint8_t*)0x200000000282 = 0x11;
*(uint8_t*)0x200000000283 = 0;
*(uint8_t*)0x200000000284 = 0;
*(uint8_t*)0x200000000285 = 1;
memcpy((void*)0x200000000700, "\x88\xa8\x00\x60\x37\x12\x00\x08\x02\x11\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff", 22);
syz_80211_inject_frame(/*mac_addr=*/0x200000000280, /*buf=*/0x200000000700, /*buf_len=*/0x1e);
return 0;
}
]
|
| 2/1 |
2026/05/17 18:09 |
action |
kernel-checkouter |
0m
Results: map[KernelSrc:/app/workdir/cache/src/e8ba5f7856c88972f1d9e8975d56731aac6008ec]
|
| 3/1 |
2026/05/17 18:09 |
action |
kernel-builder |
31m
Results: map[KernelObj:/app/workdir/cache/build/6328d7ee7e901dc74c691d3bc67f305996f34aa6]
|
| 4/1 |
2026/05/17 18:41 |
action |
codesearch-prepare |
23m
Results: map[Index:codesearch-index]
|
| 5/1 |
2026/05/17 19:04 |
agent |
expert |
3m
Model:
Results: map[DenialOfService:false Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:true VMGuestTrigger:false VMHostTrigger:false]
Instruction:
You are an experienced Linux kernel security engineer. Your task is to analyze given kernel bug report
and determine its security impact based on the following dimensions.
Use the provided tools to examine the source code, check for capability checks (e.g., capable(), ns_capable()),
and understand the nature of the bug. Analyze the given kernel build and configuration.
You can check the kernel config by grepping ".config" file; you can check kernel cmdline by greeping
".config" file for "CONFIG_CMDLINE=". Assume sysctl parameters have default values.
But analyze for the corresponding production build w/o debugging tools enabled (like KASAN, KMSAN, UBSAN).
Don't make assumptions; verify them with source code access. Try different strategies when analyzing the bug:
- think of ways in which the vulnerable code is unreachable
- or the other way around: try to come up with different ideas of how an unprivileged user can reach the bug
If still unsure err on the side of the bug being non-exploitable/not-accessible.
In the final reply, provide a reasoning for your assessment.
Analysis dimensions:
* Exploitable:
Determine if the bug can result in memory corruption or elevated privileges.
Memory safety issues are almost always exploitable (KASAN or UBSAN reports for use-after-free, out-of-bounds;
refcounting issues, corrupted lists, etc). When kernel is crashing on a completly wild pointer access
(e.g. user-space address, or non-canonical address, but not on NULL or address corresponding to KASAN shadow
for NULL address), including both data accesses and control tranfers, that's also usually implies possibility
of exploitation. Such reports usually say "unable to handle kernel paging request".
Uses of uninitialized values detected by KMSAN may be exploitable b/c attacker frequently can affect uninit
values with spraying techniques. However, for these exploitabability depends on how exactly the uninit value
is used in the code, and what it affects.
Think of what happens after the bug is triggered. Some bugs cause kernel panic and halt execution,
they are harder to exploit. For example, BUG reports halts the kernel. However, WARNING reports don't halt
execution in production builds. Debug bug detection tools (like KASAN, KMSAN, KCSAN, UBSAN) are also not enabled
in production builds, so attacker can freely exploit these bugs w/o being detected by these tools.
If you see an integer overflow, think how the overflowed value used later (if it's used as allocation size,
or an array index). If you see an out-of-bounds read, think if it's followed by an out-of-bounds write as well.
Some KCSAN data-races may be exploitable by skilled attackers as well. Think what data structures got corrupted
as the result of data races and how. However, note that kernel has lots of "benign" data races that don't lead
to any runtime misbehavior at all.
* Denial Of Service:
Determine if the bug can result in denial-of-service. Most bugs can, since they cause system crash,
hangs, deadlocks, or resource leaks. This is mostly applicable to WARNING bugs that won't cause system crash
in production. For these think what will be consequences of the violation of the kernel assumptions flagged
by the WARNING. In some cases the unexpected condition is also properly handled by the normal control flow
(e.g. with "if (WARN_ON(...))"), these won't cause denial-of-service. If the condition is not handled,
then it may or may not cause denial-of-service.
* Accessible From Unprivileged Processes:
Determine if the bug can be reached from a typical (non-root) user process that does NOT have any special capabilities
(like CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_NET_RAW, CAP_PERFMON) or access to device nodes restricted to root.
Assume that unprivileged_bpf_disabled=1, that is eBPF loading is not accessible. However, cBPF (classical BPF)
is still accessible to non-root processes.
Assume that user namespaces are not accessible, that is, the process cannot get the mentioned capabilities even
within a new user namespace (checked by ns_capable() function in the kernel sources).
* Accessible From User Namespaces:
Determine if the bug can be reached within a user-namespace where the process has all capabilities
(including CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_NET_RAW, CAP_PERFMON). Such capabilities are checked with ns_capable()
function in the kernel sources.
* VM Guest Trigger:
Determine if the bug can be triggered from the context of a typical KVM guest (e.g., set up by a QEMU VMM).
Consider accesses to standard Linux host paravirtualized features (virtio-blk, virtio-net, etc.),
and handling of VM exits in the KVM code.
* VM Host Trigger in The Confidetial Computing Context:
Determine if the bug can be triggered in a confidential computing guest kernel from the context of a KVM host.
Consider access to standard Linux guest paravirtualized features (virtio-blk, virtio-net, etc.).
* Ethernet Network Trigger:
Determine if the bug can be triggered by processing ingress network Ethernet traffic, either directly (network stack)
or via drivers exposed to network data.
* Other Remote Trigger:
Determine if the bug can be triggered by processing remote traffic other than Ethernet (Wifi, Bluetooth, NFC, etc).
* Peripheral Trigger:
Determine if the bug can be triggered via an untrusted peripheral device that can be physically plugged
into a system, such as a USB device or a niche hardware driver handling external hardware inputs.
This is particularly important for mobile and desktop environments where users can plug in unknown devices.
* Malicious Filesystem Trigger:
Determine if the bug can be triggered by the kernel mounting and parsing a malicious filesystem image.
This is highly critical for Desktop and Mobile environments where external media or downloaded images
might be auto-mounted.
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt:
The kernel bug report is:
------------[ cut here ]------------
intf 08:02:11:00:00:01 [link=0]: bad STA 00:00:00:ff:ff:ff bandwidth 20 MHz (0) > channel config 10 MHz (7)
WARNING: drivers/net/wireless/virtual/mac80211_hwsim.c:2832 at mac80211_hwsim_sta_rc_update+0x696/0x860 drivers/net/wireless/virtual/mac80211_hwsim.c:2829, CPU#1: kworker/u8:8/3457
Modules linked in:
CPU: 1 UID: 0 PID: 3457 Comm: kworker/u8:8 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/18/2026
Workqueue: events_unbound cfg80211_wiphy_work
RIP: 0010:mac80211_hwsim_sta_rc_update+0x6f4/0x860 drivers/net/wireless/virtual/mac80211_hwsim.c:2829
Code: 85 d2 00 00 00 45 8b 36 44 89 f7 e8 76 21 00 00 48 8b 7c 24 28 48 8b 74 24 30 89 ea 48 8b 4c 24 10 41 89 d8 45 89 f9 41 56 50 <67> 48 0f b9 3a 48 83 c4 10 e9 08 ff ff ff e8 69 f7 bc fa 90 0f 0b
RSP: 0018:ffffc9000d5ef738 EFLAGS: 00010293
RAX: 000000000000000a RBX: 0000000000000014 RCX: ffff8880312d8ec0
RDX: 0000000000000000 RSI: ffff8880581a72c2 RDI: ffffffff90401f30
RBP: 0000000000000000 R08: 0000000000000014 R09: 0000000000000000
R10: 000000000000000d R11: 0000000000000000 R12: 0000000000000000
R13: dffffc0000000000 R14: 0000000000000007 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff888125331000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffdc542efcc CR3: 000000001be92000 CR4: 00000000003526f0
Call Trace:
<TASK>
mac80211_hwsim_sta_add+0xa4/0x350 drivers/net/wireless/virtual/mac80211_hwsim.c:2849
drv_sta_add net/mac80211/driver-ops.h:470 [inline]
drv_sta_state+0x86a/0x17c0 net/mac80211/driver-ops.c:155
sta_info_insert_drv_state net/mac80211/sta_info.c:842 [inline]
sta_info_insert_finish net/mac80211/sta_info.c:950 [inline]
sta_info_insert_rcu+0x16f8/0x26e0 net/mac80211/sta_info.c:1027
ieee80211_ocb_finish_sta net/mac80211/ocb.c:105 [inline]
ieee80211_ocb_work+0x324/0x590 net/mac80211/ocb.c:139
cfg80211_wiphy_work+0x2cf/0x460 net/wireless/core.c:513
process_one_work kernel/workqueue.c:3302 [inline]
process_scheduled_works+0xb5d/0x1860 kernel/workqueue.c:3385
worker_thread+0xa53/0xfc0 kernel/workqueue.c:3466
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
----------------
Code disassembly (best guess):
0: 85 d2 test %edx,%edx
2: 00 00 add %al,(%rax)
4: 00 45 8b add %al,-0x75(%rbp)
7: 36 44 89 f7 ss mov %r14d,%edi
b: e8 76 21 00 00 call 0x2186
10: 48 8b 7c 24 28 mov 0x28(%rsp),%rdi
15: 48 8b 74 24 30 mov 0x30(%rsp),%rsi
1a: 89 ea mov %ebp,%edx
1c: 48 8b 4c 24 10 mov 0x10(%rsp),%rcx
21: 41 89 d8 mov %ebx,%r8d
24: 45 89 f9 mov %r15d,%r9d
27: 41 56 push %r14
29: 50 push %rax
* 2a: 67 48 0f b9 3a ud1 (%edx),%rdi <-- trapping instruction
2f: 48 83 c4 10 add $0x10,%rsp
33: e9 08 ff ff ff jmp 0xffffff40
38: e8 69 f7 bc fa call 0xfabcf7a6
3d: 90 nop
3e: 0f 0b ud2
It is reproducible with the followint program.
Keep in mind that it may lack the precise threading, sandboxing, and some arguments of a working reproducer.
But it should give an idea of the involved syscalls.
// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <endian.h>
#include <errno.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/genetlink.h>
#include <linux/if_addr.h>
#include <linux/if_ether.h>
#include <linux/if_link.h>
#include <linux/in6.h>
#include <linux/neighbour.h>
#include <linux/net.h>
#include <linux/netlink.h>
#include <linux/nl80211.h>
#include <linux/rtnetlink.h>
#include <linux/veth.h>
struct nlmsg {
char* pos;
int nesting;
struct nlattr* nested[8];
char buf[4096];
};
static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
const void* data, int size)
{
memset(nlmsg, 0, sizeof(*nlmsg));
struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
hdr->nlmsg_type = typ;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
memcpy(hdr + 1, data, size);
nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
}
static void netlink_attr(struct nlmsg* nlmsg, int typ,
const void* data, int size)
{
struct nlattr* attr = (struct nlattr*)nlmsg->pos;
attr->nla_len = sizeof(*attr) + size;
attr->nla_type = typ;
if (size > 0)
memcpy(attr + 1, data, size);
nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
}
static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
uint16_t reply_type, int* reply_len, bool dofail)
{
if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
exit(1);
struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
struct sockaddr_nl addr;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
if (n != (ssize_t)hdr->nlmsg_len) {
if (dofail)
exit(1);
return -1;
}
n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
if (reply_len)
*reply_len = 0;
if (n < 0) {
if (dofail)
exit(1);
return -1;
}
if (n < (ssize_t)sizeof(struct nlmsghdr)) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
if (hdr->nlmsg_type == NLMSG_DONE)
return 0;
if (reply_len && hdr->nlmsg_type == reply_type) {
*reply_len = n;
return 0;
}
if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
if (hdr->nlmsg_type != NLMSG_ERROR) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
errno = -((struct nlmsgerr*)(hdr + 1))->error;
return -errno;
}
static int netlink_query_family_id(struct nlmsg* nlmsg, int sock, const char* family_name, bool dofail)
{
struct genlmsghdr genlhdr;
memset(&genlhdr, 0, sizeof(genlhdr));
genlhdr.cmd = CTRL_CMD_GETFAMILY;
netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, family_name, strnlen(family_name, GENL_NAMSIZ - 1) + 1);
int n = 0;
int err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n, dofail);
if (err < 0) {
return -1;
}
uint16_t id = 0;
struct nlattr* attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(genlhdr)));
for (; (char*)attr < nlmsg->buf + n; attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
id = *(uint16_t*)(attr + 1);
break;
}
}
if (!id) {
errno = EINVAL;
return -1;
}
recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
return id;
}
#define WIFI_INITIAL_DEVICE_COUNT 2
#define WIFI_MAC_BASE { 0x08, 0x02, 0x11, 0x00, 0x00, 0x00}
#define WIFI_IBSS_BSSID { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50}
#define WIFI_IBSS_SSID { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}
#define WIFI_DEFAULT_FREQUENCY 2412
#define WIFI_DEFAULT_SIGNAL 0
#define WIFI_DEFAULT_RX_RATE 1
#define HWSIM_CMD_REGISTER 1
#define HWSIM_CMD_FRAME 2
#define HWSIM_CMD_NEW_RADIO 4
#define HWSIM_ATTR_SUPPORT_P2P_DEVICE 14
#define HWSIM_ATTR_PERM_ADDR 22
static long syz_genetlink_get_family_id(volatile long name, volatile long sock_arg)
{
int fd = sock_arg;
if (fd < 0) {
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
if (fd == -1) {
return -1;
}
}
struct nlmsg nlmsg_tmp;
int ret = netlink_query_family_id(&nlmsg_tmp, fd, (char*)name, false);
if ((int)sock_arg < 0)
close(fd);
if (ret < 0) {
return -1;
}
return ret;
}
#define HWSIM_ATTR_RX_RATE 5
#define HWSIM_ATTR_SIGNAL 6
#define HWSIM_ATTR_ADDR_RECEIVER 1
#define HWSIM_ATTR_FRAME 3
#define WIFI_MAX_INJECT_LEN 2048
static int hwsim_register_socket(struct nlmsg* nlmsg, int sock, int hwsim_family)
{
struct genlmsghdr genlhdr;
memset(&genlhdr, 0, sizeof(genlhdr));
genlhdr.cmd = HWSIM_CMD_REGISTER;
netlink_init(nlmsg, hwsim_family, 0, &genlhdr, sizeof(genlhdr));
int err = netlink_send_ext(nlmsg, sock, 0, NULL, false);
if (err < 0) {
}
return err;
}
static int hwsim_inject_frame(struct nlmsg* nlmsg, int sock, int hwsim_family, uint8_t* mac_addr, uint8_t* data, int len)
{
struct genlmsghdr genlhdr;
uint32_t rx_rate = WIFI_DEFAULT_RX_RATE;
uint32_t signal = WIFI_DEFAULT_SIGNAL;
memset(&genlhdr, 0, sizeof(genlhdr));
genlhdr.cmd = HWSIM_CMD_FRAME;
netlink_init(nlmsg, hwsim_family, 0, &genlhdr, sizeof(genlhdr));
netlink_attr(nlmsg, HWSIM_ATTR_RX_RATE, &rx_rate, sizeof(rx_rate));
netlink_attr(nlmsg, HWSIM_ATTR_SIGNAL, &signal, sizeof(signal));
netlink_attr(nlmsg, HWSIM_ATTR_ADDR_RECEIVER, mac_addr, ETH_ALEN);
netlink_attr(nlmsg, HWSIM_ATTR_FRAME, data, len);
int err = netlink_send_ext(nlmsg, sock, 0, NULL, false);
if (err < 0) {
}
return err;
}
static long syz_80211_inject_frame(volatile long a0, volatile long a1, volatile long a2)
{
uint8_t* mac_addr = (uint8_t*)a0;
uint8_t* buf = (uint8_t*)a1;
int buf_len = (int)a2;
struct nlmsg tmp_msg;
if (buf_len < 0 || buf_len > WIFI_MAX_INJECT_LEN) {
return -1;
}
int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
if (sock < 0) {
return -1;
}
int hwsim_family_id = netlink_query_family_id(&tmp_msg, sock, "MAC80211_HWSIM", false);
if (hwsim_family_id < 0) {
close(sock);
return -1;
}
int ret = hwsim_register_socket(&tmp_msg, sock, hwsim_family_id);
if (ret < 0) {
close(sock);
return -1;
}
ret = hwsim_inject_frame(&tmp_msg, sock, hwsim_family_id, mac_addr, buf, buf_len);
close(sock);
if (ret < 0) {
return -1;
}
return 0;
}
uint64_t r[4] = {0xffffffffffffffff, 0x0, 0xffffffffffffffff, 0x0};
int main(void)
{
syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
const char* reason;
(void)reason;
intptr_t res = 0;
if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
// socket$nl_generic arguments: [
// domain: const = 0x10 (8 bytes)
// type: const = 0x3 (8 bytes)
// proto: const = 0x10 (4 bytes)
// ]
// returns sock_nl_generic
res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0x10);
if (res != -1)
r[0] = res;
// ioctl$sock_SIOCGIFINDEX_80211 arguments: [
// fd: sock (resource)
// cmd: const = 0x8933 (4 bytes)
// arg: ptr[out, ifreq_dev_t[nl80211_devnames, nl80211_ifindex]] {
// ifreq_dev_t[nl80211_devnames, nl80211_ifindex] {
// ifr_ifrn: buffer: {77 6c 61 6e 31 00 00 00 00 00 00 00 00 00 00 00} (length 0x10)
// elem: nl80211_ifindex (resource)
// pad = 0x0 (20 bytes)
// }
// }
// ]
memcpy((void*)0x200000000100, "wlan1\000\000\000\000\000\000\000\000\000\000\000", 16);
res = syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x8933, /*arg=*/0x200000000100ul);
if (res != -1)
r[1] = *(uint32_t*)0x200000000110;
// socket$nl_generic arguments: [
// domain: const = 0x10 (8 bytes)
// type: const = 0x3 (8 bytes)
// proto: const = 0x10 (4 bytes)
// ]
// returns sock_nl_generic
res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0x10);
if (res != -1)
r[2] = res;
// syz_genetlink_get_family_id$nl80211 arguments: [
// name: ptr[in, buffer] {
// buffer: {6e 6c 38 30 32 31 31 00} (length 0x8)
// }
// fd: sock_nl_generic (resource)
// ]
// returns nl80211_family_id
memcpy((void*)0x200000000200, "nl80211\000", 8);
res = -1;
res = syz_genetlink_get_family_id(/*name=*/0x200000000200, /*fd=*/-1);
if (res != -1)
r[3] = res;
// sendmsg$NL80211_CMD_SET_INTERFACE arguments: [
// fd: sock_nl_generic (resource)
// msg: ptr[in, msghdr_netlink[netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]]] {
// msghdr_netlink[netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]] {
// addr: nil
// addrlen: len = 0x0 (4 bytes)
// pad = 0x0 (4 bytes)
// vec: ptr[in, iovec[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]]] {
// iovec[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]] {
// addr: ptr[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface]] {
// netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload], nl80211_policy$set_interface] {
// len: len = 0x24 (4 bytes)
// type: nl80211_family_id (resource)
// flags: netlink_msg_flags = 0x5 (2 bytes)
// seq: int32 = 0x0 (4 bytes)
// pid: int32 = 0x0 (4 bytes)
// payload: msg_nl80211_payload[NL80211_CMD_SET_INTERFACE, nl80211_wdev_payload] {
// genl_hdr: genlmsghdr_t[NL80211_CMD_SET_INTERFACE] {
// cmd: const = 0x6 (1 bytes)
// version: const = 0x0 (1 bytes)
// reserved: const = 0x0 (2 bytes)
// }
// payload: nl80211_wdev_payload {
// NL80211_ATTR_IFINDEX: union optional[nlattr[NL80211_ATTR_IFINDEX, nl80211_ifindex]] {
// val: nlattr_t[const[NL80211_ATTR_IFINDEX, int16], nl80211_ifindex] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x3 (2 bytes)
// payload: nl80211_ifindex (resource)
// size: buffer: {} (length 0x0)
// }
// }
// NL80211_ATTR_WDEV: union optional[nlattr[NL80211_ATTR_WDEV, nl80211_wdev]] {
// void: buffer: {} (length 0x0)
// }
// }
// }
// attrs: array[nl80211_policy$set_interface] {
// union nl80211_policy$set_interface {
// NL80211_ATTR_IFTYPE: nlattr_t[const[NL80211_ATTR_IFTYPE, int16], flags[nl80211_iftype, int32]] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x5 (2 bytes)
// payload: nl80211_iftype = 0xb (4 bytes)
// size: buffer: {} (length 0x0)
// }
// }
// }
// }
// }
// len: len = 0x24 (8 bytes)
// }
// }
// vlen: const = 0x1 (8 bytes)
// ctrl: const = 0x0 (8 bytes)
// ctrllen: const = 0x0 (8 bytes)
// f: send_flags = 0x400c000 (4 bytes)
// pad = 0x0 (4 bytes)
// }
// }
// f: send_flags = 0x0 (8 bytes)
// ]
*(uint64_t*)0x200000000340 = 0;
*(uint32_t*)0x200000000348 = 0;
*(uint64_t*)0x200000000350 = 0x200000000300;
*(uint64_t*)0x200000000300 = 0x200000000000;
*(uint32_t*)0x200000000000 = 0x24;
*(uint16_t*)0x200000000004 = r[3];
*(uint16_t*)0x200000000006 = 5;
*(uint32_t*)0x200000000008 = 0;
*(uint32_t*)0x20000000000c = 0;
*(uint8_t*)0x200000000010 = 6;
*(uint8_t*)0x200000000011 = 0;
*(uint16_t*)0x200000000012 = 0;
*(uint16_t*)0x200000000014 = 8;
*(uint16_t*)0x200000000016 = 3;
*(uint32_t*)0x200000000018 = r[1];
*(uint16_t*)0x20000000001c = 8;
*(uint16_t*)0x20000000001e = 5;
*(uint32_t*)0x200000000020 = 0xb;
*(uint64_t*)0x200000000308 = 0x24;
*(uint64_t*)0x200000000358 = 1;
*(uint64_t*)0x200000000360 = 0;
*(uint64_t*)0x200000000368 = 0;
*(uint32_t*)0x200000000370 = 0x400c000;
syscall(__NR_sendmsg, /*fd=*/r[2], /*msg=*/0x200000000340ul, /*f=*/0ul);
// sendmsg$NL80211_CMD_JOIN_OCB arguments: [
// fd: sock_nl_generic (resource)
// msg: ptr[in, msghdr_netlink[netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]]] {
// msghdr_netlink[netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]] {
// addr: nil
// addrlen: len = 0x0 (4 bytes)
// pad = 0x0 (4 bytes)
// vec: ptr[in, iovec[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]]] {
// iovec[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]] {
// addr: ptr[in, netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params]] {
// netlink_msg_t[nl80211_family_id, msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload], nl80211_policy$chandef_params] {
// len: len = 0x2c (4 bytes)
// type: nl80211_family_id (resource)
// flags: netlink_msg_flags = 0x1 (2 bytes)
// seq: int32 = 0x70bd28 (4 bytes)
// pid: int32 = 0x25dfdbff (4 bytes)
// payload: msg_nl80211_payload[NL80211_CMD_JOIN_OCB, nl80211_wdev_payload] {
// genl_hdr: genlmsghdr_t[NL80211_CMD_JOIN_OCB] {
// cmd: const = 0x6c (1 bytes)
// version: const = 0x0 (1 bytes)
// reserved: const = 0x0 (2 bytes)
// }
// payload: nl80211_wdev_payload {
// NL80211_ATTR_IFINDEX: union optional[nlattr[NL80211_ATTR_IFINDEX, nl80211_ifindex]] {
// val: nlattr_t[const[NL80211_ATTR_IFINDEX, int16], nl80211_ifindex] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x3 (2 bytes)
// payload: nl80211_ifindex (resource)
// size: buffer: {} (length 0x0)
// }
// }
// NL80211_ATTR_WDEV: union optional[nlattr[NL80211_ATTR_WDEV, nl80211_wdev]] {
// void: buffer: {} (length 0x0)
// }
// }
// }
// attrs: array[nl80211_policy$chandef_params] {
// union nl80211_policy$chandef_params {
// NL80211_ATTR_WIPHY_FREQ: nlattr_t[const[NL80211_ATTR_WIPHY_FREQ, int16], ieee80211_frequency_mhz[int32]] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x26 (2 bytes)
// payload: union ieee80211_frequency_mhz[int32] {
// default: const = 0x96c (4 bytes)
// }
// size: buffer: {} (length 0x0)
// }
// }
// union nl80211_policy$chandef_params {
// NL80211_ATTR_CHANNEL_WIDTH: nlattr_t[const[NL80211_ATTR_CHANNEL_WIDTH, int16], flags[nl80211_channel_widths, int32]] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x9f (2 bytes)
// payload: nl80211_channel_widths = 0x7 (4 bytes)
// size: buffer: {} (length 0x0)
// }
// }
// }
// }
// }
// len: len = 0x2c (8 bytes)
// }
// }
// vlen: const = 0x1 (8 bytes)
// ctrl: const = 0x0 (8 bytes)
// ctrllen: const = 0x0 (8 bytes)
// f: send_flags = 0x24004015 (4 bytes)
// pad = 0x0 (4 bytes)
// }
// }
// f: send_flags = 0x448d0 (8 bytes)
// ]
*(uint64_t*)0x200000000240 = 0;
*(uint32_t*)0x200000000248 = 0;
*(uint64_t*)0x200000000250 = 0x200000000200;
*(uint64_t*)0x200000000200 = 0x200000000800;
*(uint32_t*)0x200000000800 = 0x2c;
*(uint16_t*)0x200000000804 = r[3];
*(uint16_t*)0x200000000806 = 1;
*(uint32_t*)0x200000000808 = 0x70bd28;
*(uint32_t*)0x20000000080c = 0x25dfdbff;
*(uint8_t*)0x200000000810 = 0x6c;
*(uint8_t*)0x200000000811 = 0;
*(uint16_t*)0x200000000812 = 0;
*(uint16_t*)0x200000000814 = 8;
*(uint16_t*)0x200000000816 = 3;
*(uint32_t*)0x200000000818 = r[1];
*(uint16_t*)0x20000000081c = 8;
*(uint16_t*)0x20000000081e = 0x26;
*(uint32_t*)0x200000000820 = 0x96c;
*(uint16_t*)0x200000000824 = 8;
*(uint16_t*)0x200000000826 = 0x9f;
*(uint32_t*)0x200000000828 = 7;
*(uint64_t*)0x200000000208 = 0x2c;
*(uint64_t*)0x200000000258 = 1;
*(uint64_t*)0x200000000260 = 0;
*(uint64_t*)0x200000000268 = 0;
*(uint32_t*)0x200000000270 = 0x24004015;
syscall(__NR_sendmsg, /*fd=*/r[0], /*msg=*/0x200000000240ul, /*f=MSG_BATCH|MSG_PROBE|MSG_NOSIGNAL|MSG_EOR|MSG_DONTWAIT|MSG_CONFIRM*/0x448d0ul);
// syz_80211_inject_frame arguments: [
// mac_addr: ptr[in, ieee80211_mac_addr] {
// union ieee80211_mac_addr {
// device_b: ieee80211_fixed_mac_addr[const[0x1, int8]] {
// byte0: const = 0x8 (1 bytes)
// byte1: const = 0x2 (1 bytes)
// byte2: const = 0x11 (1 bytes)
// byte3: const = 0x0 (1 bytes)
// byte4: const = 0x0 (1 bytes)
// byte5: const = 0x1 (1 bytes)
// }
// }
// }
// buf: ptr[inout, array[ANYUNION]] {
// array[ANYUNION] {
// union ANYUNION {
// ANYBLOB: buffer: {88 a8 00 60 37 12 00 08 02 11 00 00 00 ff ff ff ff ff ff ff ff ff} (length 0x16)
// }
// }
// }
// buf_len: len = 0x1e (8 bytes)
// ]
*(uint8_t*)0x200000000280 = 8;
*(uint8_t*)0x200000000281 = 2;
*(uint8_t*)0x200000000282 = 0x11;
*(uint8_t*)0x200000000283 = 0;
*(uint8_t*)0x200000000284 = 0;
*(uint8_t*)0x200000000285 = 1;
memcpy((void*)0x200000000700, "\x88\xa8\x00\x60\x37\x12\x00\x08\x02\x11\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff", 22);
syz_80211_inject_frame(/*mac_addr=*/0x200000000280, /*buf=*/0x200000000700, /*buf_len=*/0x1e);
return 0;
}
Reply: Based on the analysis of the bug report and the kernel source code, here is the assessment of the bug's security impact:
**1. Exploitable: False**
The bug is a `WARN` in `mac80211_hwsim_sta_rc_update` that triggers when a station's bandwidth (`bw`) is greater than the channel's configured bandwidth (`confbw`). The `WARN` macro is used as a sanity check. In production builds, this merely prints a warning message to the kernel log and continues execution. The `bw` variable is not used for any subsequent logic or memory accesses within the function, and `mac80211_hwsim` (being a software simulator) does not rely on this bandwidth value for any critical operations. Therefore, this bug does not lead to memory corruption, out-of-bounds accesses, or privilege escalation.
**2. Denial Of Service: False**
Since this is a `WARNING` and not a `BUG`, it does not halt the kernel in production builds (assuming `panic_on_warn` is not set). The violation of the assumption (station bandwidth > channel bandwidth) is not handled, but it also has no adverse consequences because the `mac80211_hwsim` driver does not use the bandwidth value for anything else. It does not cause a system crash, hang, deadlock, or resource leak. The only consequence is a log message.
**3. Accessible From Unprivileged Processes: False**
The bug is triggered by injecting an 802.11 frame into a simulated radio configured in OCB (Outside the Context of a BSS) mode. To configure an interface in OCB mode, the process must send the `NL80211_CMD_JOIN_OCB` netlink command, which requires the `GENL_UNS_ADMIN_PERM` flag (meaning it requires `CAP_NET_ADMIN` in the user namespace). Furthermore, injecting frames into the `mac80211_hwsim` simulator requires registering a socket via `HWSIM_CMD_REGISTER`, which also requires `CAP_NET_ADMIN`. Thus, an unprivileged process without namespace access cannot trigger this bug.
**4. Accessible From User Namespaces: True**
Both the `MAC80211_HWSIM` and `nl80211` netlink families have `.netnsok = true`, meaning they are accessible within network namespaces. The required commands (`HWSIM_CMD_REGISTER`, `NL80211_CMD_SET_INTERFACE`, `NL80211_CMD_JOIN_OCB`) use the `GENL_UNS_ADMIN_PERM` flag, which allows execution if the process has `CAP_NET_ADMIN` in the user namespace that owns the network namespace. Therefore, an unprivileged user can create a new user/network namespace, gain the necessary capabilities within it, and trigger the bug.
**5. VM Guest Trigger: False**
While `mac80211_hwsim` does have a virtio driver (`VIRTIO_ID_MAC80211_HWSIM`), it is a testing tool and not a standard paravirtualized feature exposed to typical KVM guests by default. The bug is triggered by user-space netlink interactions within the OS where the simulator is running, not by standard guest-to-host or host-to-guest VM exits.
**6. VM Host Trigger in The Confidential Computing Context: False**
Even if the host exposes the `mac80211_hwsim` virtio device to a guest, the bug requires the guest to have already configured a wireless interface in OCB mode (which is not a default configuration). The host cannot force the guest to configure OCB mode, so it cannot reliably trigger the bug in the guest.
**7. Ethernet Network Trigger: False**
The bug involves processing 802.11 wireless frames, not Ethernet traffic. Furthermore, it occurs within a software-simulated radio (`mac80211_hwsim`), which does not receive traffic from real physical networks.
**8. Other Remote Trigger: False**
Because the bug is located in `mac80211_hwsim.c` (a software simulator for testing), it cannot be triggered remotely over the air. Real wireless drivers have their own station addition callbacks and do not use the simulator's code path.
**9. Peripheral Trigger: False**
The bug is in a virtual/simulated driver, not a driver for a physical peripheral device. Plugging in a malicious USB or other peripheral will not trigger this code path.
**10. Malicious Filesystem Trigger: False**
The bug is entirely within the wireless networking subsystem and has no interaction with filesystem mounting or parsing.
|
| 6/2 |
2026/05/17 19:04 |
llm |
expert |
0m
Model:
Tokens:
input: 15480
output: 63
thoughts: 204
Thoughts: **Analyzing a Kernel Bug Report**
Okay, so I've got this kernel bug report to look into. It seems like there's a problem with `mac80211_hwsim`, specifically around line 2832 of `drivers/net/wireless/virtual/mac80211_hwsim.c`. The error message is pretty clear: a "bad STA" is trying to use more bandwidth (20 MHz) than the channel configuration allows (10 MHz). This is a classic mismatch that will definitely cause problems, likely a loss of connectivity or at least degraded performance.
The report also gives me a little more information, the STA's MAC address `00:00:00:ff:ff:ff` and the interface `intf 08:02:11:00:00:01` involved. I will need to look deeper in the source code around line 2832 to understand what's triggering this bandwidth misconfiguration, where the STA's reported bandwidth originates, and how it's compared to the channel configuration. It will be important to understand how `mac80211_hwsim` handles STA association and rate control in this virtual environment. The presence of the CPU and kworker details suggests this likely involves a background worker and potentially a race condition or incorrect state update. My next step is a deep dive into the code.
|
| 7/2 |
2026/05/17 19:04 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:mac80211_hwsim_sta_rc_update]
Results: map[SourceCode:2781: static void
2782: mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw,
2783: struct ieee80211_vif *vif,
2784: struct ieee80211_link_sta *link_sta,
2785: u32 changed)
2786: {
2787: struct mac80211_hwsim_data *data = hw->priv;
2788: struct ieee80211_sta *sta = link_sta->sta;
2789: u32 bw = U32_MAX;
2790: int link_id;
2791:
2792: rcu_read_lock();
2793: for (link_id = 0;
2794: link_id < ARRAY_SIZE(vif->link_conf);
2795: link_id++) {
2796: enum nl80211_chan_width confbw = NL80211_CHAN_WIDTH_20_NOHT;
2797: struct ieee80211_bss_conf *vif_conf;
2798:
2799: link_sta = rcu_dereference(sta->link[link_id]);
2800:
2801: if (!link_sta)
2802: continue;
2803:
2804: switch (link_sta->bandwidth) {
2805: #define C(_bw) case IEEE80211_STA_RX_BW_##_bw: bw = _bw; break
2806: C(20);
2807: C(40);
2808: C(80);
2809: C(160);
2810: C(320);
2811: #undef C
2812: }
2813:
2814: if (!data->use_chanctx) {
2815: confbw = data->bw;
2816: } else {
2817: struct ieee80211_chanctx_conf *chanctx_conf;
2818:
2819: vif_conf = rcu_dereference(vif->link_conf[link_id]);
2820: if (WARN_ON(!vif_conf))
2821: continue;
2822:
2823: chanctx_conf = rcu_dereference(vif_conf->chanctx_conf);
2824:
2825: if (!WARN_ON(!chanctx_conf))
2826: confbw = chanctx_conf->def.width;
2827: }
2828:
2829: WARN(bw > hwsim_get_chanwidth(confbw),
2830: "intf %pM [link=%d]: bad STA %pM bandwidth %d MHz (%d) > channel config %d MHz (%d)\n",
2831: vif->addr, link_id, sta->addr, bw, sta->deflink.bandwidth,
2832: hwsim_get_chanwidth(data->bw), data->bw);
2833:
2834:
2835: }
2836: rcu_read_unlock();
2837:
2838:
2839: }
SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c]
|
| 8/2 |
2026/05/17 19:04 |
llm |
expert |
0m
Model:
Tokens:
input: 17032
output: 24
thoughts: 245
Thoughts: **Analyzing a mac80211_hwsim Warning**
Okay, so I've got a warning at line 2829 â looks like a bandwidth mismatch in `mac80211_hwsim_sta_rc_update`. It's a `WARN` macro, so it's not a critical error, but certainly worth investigating. The warning is specifically flagging that the station bandwidth (`bw`) is exceeding the configured channel width retrieved via `hwsim_get_chanwidth`. This makes sense in the context of `mac80211_hwsim`, which, if I recall correctly, is a software simulation layer for 802.11 radios within mac80211.
The interesting bit is how this is being triggered. The reproducer leverages `syz_80211_inject_frame`. This points towards a netlink interaction with the `MAC80211_HWSIM` family. Since a user-space program is doing the injection, I need to understand whether access to `MAC80211_HWSIM` is restricted to privileged processes (i.e. root). This could be critical for determining the severity of the issue and potential security implications. If it's accessible from unprivileged code, it could introduce a vulnerability. I need to dig into the access control for that netlink family right away.
|
| 9/2 |
2026/05/17 19:04 |
tool |
grepper |
0m
Args: map[Expression:MAC80211_HWSIM]
Results: map[Output:drivers/net/wireless/virtual/Kconfig:1:config MAC80211_HWSIM
drivers/net/wireless/virtual/Kconfig-2- tristate "Simulated radio testing tool for mac80211"
--
drivers/net/wireless/virtual/Makefile:1:obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
drivers/net/wireless/virtual/Makefile-2-
--
drivers/net/wireless/virtual/mac80211_hwsim.c=796=static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr)
--
drivers/net/wireless/virtual/mac80211_hwsim.c-800-
drivers/net/wireless/virtual/mac80211_hwsim.c:801:/* MAC80211_HWSIM netlink family */
drivers/net/wireless/virtual/mac80211_hwsim.c-802-static struct genl_family hwsim_genl_family;
--
drivers/net/wireless/virtual/mac80211_hwsim.c=808=static const struct genl_multicast_group hwsim_mcgrps[] = {
--
drivers/net/wireless/virtual/mac80211_hwsim.c-811-
drivers/net/wireless/virtual/mac80211_hwsim.c:812:/* MAC80211_HWSIM netlink policy */
drivers/net/wireless/virtual/mac80211_hwsim.c-813-
--
drivers/net/wireless/virtual/mac80211_hwsim.c=912=static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
--
drivers/net/wireless/virtual/mac80211_hwsim.c-948-
drivers/net/wireless/virtual/mac80211_hwsim.c:949:/* MAC80211_HWSIM virtio queues */
drivers/net/wireless/virtual/mac80211_hwsim.c-950-static struct virtqueue *hwsim_vqs[HWSIM_NUM_VQS];
--
drivers/net/wireless/virtual/mac80211_hwsim.c=1595=static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)
--
drivers/net/wireless/virtual/mac80211_hwsim.c-1599- if (rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
drivers/net/wireless/virtual/mac80211_hwsim.c:1600: result |= MAC80211_HWSIM_TX_RC_USE_RTS_CTS;
drivers/net/wireless/virtual/mac80211_hwsim.c-1601- if (rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
drivers/net/wireless/virtual/mac80211_hwsim.c:1602: result |= MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT;
drivers/net/wireless/virtual/mac80211_hwsim.c-1603- if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
drivers/net/wireless/virtual/mac80211_hwsim.c:1604: result |= MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE;
drivers/net/wireless/virtual/mac80211_hwsim.c-1605- if (rate->flags & IEEE80211_TX_RC_MCS)
drivers/net/wireless/virtual/mac80211_hwsim.c:1606: result |= MAC80211_HWSIM_TX_RC_MCS;
drivers/net/wireless/virtual/mac80211_hwsim.c-1607- if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD)
drivers/net/wireless/virtual/mac80211_hwsim.c:1608: result |= MAC80211_HWSIM_TX_RC_GREEN_FIELD;
drivers/net/wireless/virtual/mac80211_hwsim.c-1609- if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
drivers/net/wireless/virtual/mac80211_hwsim.c:1610: result |= MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH;
drivers/net/wireless/virtual/mac80211_hwsim.c-1611- if (rate->flags & IEEE80211_TX_RC_DUP_DATA)
drivers/net/wireless/virtual/mac80211_hwsim.c:1612: result |= MAC80211_HWSIM_TX_RC_DUP_DATA;
drivers/net/wireless/virtual/mac80211_hwsim.c-1613- if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
drivers/net/wireless/virtual/mac80211_hwsim.c:1614: result |= MAC80211_HWSIM_TX_RC_SHORT_GI;
drivers/net/wireless/virtual/mac80211_hwsim.c-1615- if (rate->flags & IEEE80211_TX_RC_VHT_MCS)
drivers/net/wireless/virtual/mac80211_hwsim.c:1616: result |= MAC80211_HWSIM_TX_RC_VHT_MCS;
drivers/net/wireless/virtual/mac80211_hwsim.c-1617- if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
drivers/net/wireless/virtual/mac80211_hwsim.c:1618: result |= MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH;
drivers/net/wireless/virtual/mac80211_hwsim.c-1619- if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
drivers/net/wireless/virtual/mac80211_hwsim.c:1620: result |= MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH;
drivers/net/wireless/virtual/mac80211_hwsim.c-1621-
--
drivers/net/wireless/virtual/mac80211_hwsim.c=3465=static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = {
--
drivers/net/wireless/virtual/mac80211_hwsim.c-3475-
drivers/net/wireless/virtual/mac80211_hwsim.c:3476:#define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats)
drivers/net/wireless/virtual/mac80211_hwsim.c-3477-
--
drivers/net/wireless/virtual/mac80211_hwsim.c=3487=static int mac80211_hwsim_get_et_sset_count(struct ieee80211_hw *hw,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-3490- if (sset == ETH_SS_STATS)
drivers/net/wireless/virtual/mac80211_hwsim.c:3491: return MAC80211_HWSIM_SSTATS_LEN;
drivers/net/wireless/virtual/mac80211_hwsim.c-3492- return 0;
--
drivers/net/wireless/virtual/mac80211_hwsim.c=3495=static void mac80211_hwsim_get_et_stats(struct ieee80211_hw *hw,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-3510-
drivers/net/wireless/virtual/mac80211_hwsim.c:3511: WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN);
drivers/net/wireless/virtual/mac80211_hwsim.c-3512-}
--
drivers/net/wireless/virtual/mac80211_hwsim.c=5553=static const u8 iftypes_ext_capa_ap[] = {
--
drivers/net/wireless/virtual/mac80211_hwsim.c-5561-
drivers/net/wireless/virtual/mac80211_hwsim.c:5562:#define MAC80211_HWSIM_MLD_CAPA_OPS \
drivers/net/wireless/virtual/mac80211_hwsim.c-5563- FIELD_PREP_CONST(IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP, \
--
drivers/net/wireless/virtual/mac80211_hwsim.c=5568=static const struct wiphy_iftype_ext_capab mac80211_hwsim_iftypes_ext_capa[] = {
--
drivers/net/wireless/virtual/mac80211_hwsim.c-5575- IEEE80211_EML_CAP_EMLMR_SUPPORT,
drivers/net/wireless/virtual/mac80211_hwsim.c:5576: .mld_capa_and_ops = MAC80211_HWSIM_MLD_CAPA_OPS,
drivers/net/wireless/virtual/mac80211_hwsim.c-5577- },
--
drivers/net/wireless/virtual/mac80211_hwsim.c=6916=static struct genl_family hwsim_genl_family __ro_after_init = {
drivers/net/wireless/virtual/mac80211_hwsim.c:6917: .name = "MAC80211_HWSIM",
drivers/net/wireless/virtual/mac80211_hwsim.c-6918- .version = 1,
--
drivers/net/wireless/virtual/mac80211_hwsim.c=7235=static void hwsim_virtio_remove(struct virtio_device *vdev)
--
drivers/net/wireless/virtual/mac80211_hwsim.c-7243-
drivers/net/wireless/virtual/mac80211_hwsim.c:7244:/* MAC80211_HWSIM virtio device id table */
drivers/net/wireless/virtual/mac80211_hwsim.c-7245-static const struct virtio_device_id id_table[] = {
drivers/net/wireless/virtual/mac80211_hwsim.c:7246: { VIRTIO_ID_MAC80211_HWSIM, VIRTIO_DEV_ANY_ID },
drivers/net/wireless/virtual/mac80211_hwsim.c-7247- { 0 }
--
drivers/net/wireless/virtual/mac80211_hwsim.h-8-
drivers/net/wireless/virtual/mac80211_hwsim.h:9:#ifndef __MAC80211_HWSIM_H
drivers/net/wireless/virtual/mac80211_hwsim.h:10:#define __MAC80211_HWSIM_H
drivers/net/wireless/virtual/mac80211_hwsim.h-11-
--
drivers/net/wireless/virtual/mac80211_hwsim.h=217=struct hwsim_tx_rate {
--
drivers/net/wireless/virtual/mac80211_hwsim.h-230- *
drivers/net/wireless/virtual/mac80211_hwsim.h:231: * @MAC80211_HWSIM_TX_RC_USE_RTS_CTS: Use RTS/CTS exchange for this rate.
drivers/net/wireless/virtual/mac80211_hwsim.h:232: * @MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT: CTS-to-self protection is required.
drivers/net/wireless/virtual/mac80211_hwsim.h-233- * This is set if the current BSS requires ERP protection.
drivers/net/wireless/virtual/mac80211_hwsim.h:234: * @MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE: Use short preamble.
drivers/net/wireless/virtual/mac80211_hwsim.h:235: * @MAC80211_HWSIM_TX_RC_MCS: HT rate.
drivers/net/wireless/virtual/mac80211_hwsim.h:236: * @MAC80211_HWSIM_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is
drivers/net/wireless/virtual/mac80211_hwsim.h-237- * split into a higher 4 bits (Nss) and lower 4 bits (MCS number)
drivers/net/wireless/virtual/mac80211_hwsim.h:238: * @MAC80211_HWSIM_TX_RC_GREEN_FIELD: Indicates whether this rate should be used
drivers/net/wireless/virtual/mac80211_hwsim.h-239- * in Greenfield mode.
drivers/net/wireless/virtual/mac80211_hwsim.h:240: * @MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be
drivers/net/wireless/virtual/mac80211_hwsim.h-241- * 40 MHz.
drivers/net/wireless/virtual/mac80211_hwsim.h:242: * @MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission
drivers/net/wireless/virtual/mac80211_hwsim.h:243: * @MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission
drivers/net/wireless/virtual/mac80211_hwsim.h-244- * (80+80 isn't supported yet)
drivers/net/wireless/virtual/mac80211_hwsim.h:245: * @MAC80211_HWSIM_TX_RC_DUP_DATA: The frame should be transmitted on both of
drivers/net/wireless/virtual/mac80211_hwsim.h-246- * the adjacent 20 MHz channels, if the current channel type is
drivers/net/wireless/virtual/mac80211_hwsim.h-247- * NL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS.
drivers/net/wireless/virtual/mac80211_hwsim.h:248: * @MAC80211_HWSIM_TX_RC_SHORT_GI: Short Guard interval should be used for this
drivers/net/wireless/virtual/mac80211_hwsim.h-249- * rate.
--
drivers/net/wireless/virtual/mac80211_hwsim.h=251=enum hwsim_tx_rate_flags {
drivers/net/wireless/virtual/mac80211_hwsim.h:252: MAC80211_HWSIM_TX_RC_USE_RTS_CTS = BIT(0),
drivers/net/wireless/virtual/mac80211_hwsim.h:253: MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT = BIT(1),
drivers/net/wireless/virtual/mac80211_hwsim.h:254: MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE = BIT(2),
drivers/net/wireless/virtual/mac80211_hwsim.h-255-
drivers/net/wireless/virtual/mac80211_hwsim.h-256- /* rate index is an HT/VHT MCS instead of an index */
drivers/net/wireless/virtual/mac80211_hwsim.h:257: MAC80211_HWSIM_TX_RC_MCS = BIT(3),
drivers/net/wireless/virtual/mac80211_hwsim.h:258: MAC80211_HWSIM_TX_RC_GREEN_FIELD = BIT(4),
drivers/net/wireless/virtual/mac80211_hwsim.h:259: MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH = BIT(5),
drivers/net/wireless/virtual/mac80211_hwsim.h:260: MAC80211_HWSIM_TX_RC_DUP_DATA = BIT(6),
drivers/net/wireless/virtual/mac80211_hwsim.h:261: MAC80211_HWSIM_TX_RC_SHORT_GI = BIT(7),
drivers/net/wireless/virtual/mac80211_hwsim.h:262: MAC80211_HWSIM_TX_RC_VHT_MCS = BIT(8),
drivers/net/wireless/virtual/mac80211_hwsim.h:263: MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH = BIT(9),
drivers/net/wireless/virtual/mac80211_hwsim.h:264: MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH = BIT(10),
drivers/net/wireless/virtual/mac80211_hwsim.h-265-};
--
drivers/net/wireless/virtual/mac80211_hwsim.h=328=enum hwsim_rate_info_attributes {
--
drivers/net/wireless/virtual/mac80211_hwsim.h-347-
drivers/net/wireless/virtual/mac80211_hwsim.h:348:#endif /* __MAC80211_HWSIM_H */
--
include/uapi/linux/virtio_ids.h-57-#define VIRTIO_ID_RPMB 28 /* virtio rpmb */
include/uapi/linux/virtio_ids.h:58:#define VIRTIO_ID_MAC80211_HWSIM 29 /* virtio mac80211-hwsim */
include/uapi/linux/virtio_ids.h-59-#define VIRTIO_ID_VIDEO_ENCODER 30 /* virtio video encoder */
]
|
| 10/2 |
2026/05/17 19:05 |
llm |
expert |
0m
Model:
Tokens:
input: 22681
output: 55
thoughts: 31
Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience, presented in the first person:
**Investigating MAC80211_HWSIM Netlink Family Capabilities**
Right, so the `MAC80211_HWSIM` is defined as a netlink family. That immediately raises a question in my mind: are there any specific security capabilities I need to consider when interacting with it? My experience tells me that some netlink families are tightly controlled, requiring elevated privileges for even basic operations. Understanding the permission model here is crucial, especially if I'm planning any sort of automation or integration. I need to quickly determine if using `MAC80211_HWSIM` requires root access, a specific Linux capability like `CAP_NET_ADMIN`, or if it operates with a more relaxed security posture. Time to dive into the documentation and source code to confirm. This is foundational before proceeding with any testing or deployment considerations.
|
| 11/2 |
2026/05/17 19:05 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:hwsim_genl_family]
Results: map[SourceCode:6916: static struct genl_family hwsim_genl_family __ro_after_init = {
6917: .name = "MAC80211_HWSIM",
6918: .version = 1,
6919: .maxattr = HWSIM_ATTR_MAX,
6920: .policy = hwsim_genl_policy,
6921: .netnsok = true,
6922: .module = THIS_MODULE,
6923: .small_ops = hwsim_ops,
6924: .n_small_ops = ARRAY_SIZE(hwsim_ops),
6925: .resv_start_op = HWSIM_CMD_REPORT_PMSR + 1, // match with __HWSIM_CMD_MAX
6926: .mcgrps = hwsim_mcgrps,
6927: .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
6928: };
SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c]
|
| 12/2 |
2026/05/17 19:05 |
llm |
expert |
0m
Model:
Tokens:
input: 23273
output: 52
thoughts: 11
Thoughts: Okay, let's dive into this. Here's my take on those "thoughts":
**Analyzing `hwsim_ops`**
Alright, let's get down to brass tacks. My initial focus here is on the `hwsim_ops` data structure or module. I'm immediately trying to mentally parse its purpose. Is it a core operational interface for a hardware simulator, a set of functions that define the operations a simulated hardware component can perform, or something else entirely? I'm already formulating questions: What level of abstraction does it operate at? Is it tied to a specific simulation framework, or is it intended to be more generic and portable? What sort of data types are involved? I'm mentally sketching out the probable fields or methods I would expect to see based on my experience. I'm considering what aspects of the simulated hardware it should handle - timing, resource allocation, event handling, perhaps even error injection. The specifics of the implementation will, of course, tell the full story, but it's important to start with the fundamental questions. Let's see what's what.
|
| 13/2 |
2026/05/17 19:05 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:hwsim_ops]
Results: map[SourceCode:6873: /* Generic Netlink operations array */
6874: static const struct genl_small_ops hwsim_ops[] = {
6875: {
6876: .cmd = HWSIM_CMD_REGISTER,
6877: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6878: .doit = hwsim_register_received_nl,
6879: .flags = GENL_UNS_ADMIN_PERM,
6880: },
6881: {
6882: .cmd = HWSIM_CMD_FRAME,
6883: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6884: .doit = hwsim_cloned_frame_received_nl,
6885: },
6886: {
6887: .cmd = HWSIM_CMD_TX_INFO_FRAME,
6888: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6889: .doit = hwsim_tx_info_frame_received_nl,
6890: },
6891: {
6892: .cmd = HWSIM_CMD_NEW_RADIO,
6893: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6894: .doit = hwsim_new_radio_nl,
6895: .flags = GENL_UNS_ADMIN_PERM,
6896: },
6897: {
6898: .cmd = HWSIM_CMD_DEL_RADIO,
6899: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6900: .doit = hwsim_del_radio_nl,
6901: .flags = GENL_UNS_ADMIN_PERM,
6902: },
6903: {
6904: .cmd = HWSIM_CMD_GET_RADIO,
6905: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6906: .doit = hwsim_get_radio_nl,
6907: .dumpit = hwsim_dump_radio_nl,
6908: },
6909: {
6910: .cmd = HWSIM_CMD_REPORT_PMSR,
6911: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6912: .doit = hwsim_pmsr_report_nl,
6913: },
6914: };
SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c]
|
| 14/2 |
2026/05/17 19:05 |
llm |
expert |
0m
Model:
Tokens:
input: 24361
output: 24
thoughts: 102
Thoughts: **Analyzing the `HWSIM_CMD_REGISTER` Command's Security Implications**
Okay, so I'm digging into this `HWSIM_CMD_REGISTER` command and I see it's got `.flags = GENL_UNS_ADMIN_PERM`. Right, `GENL_UNS_ADMIN_PERM`... that triggers a requirement for `CAP_NET_ADMIN` in the *user namespace*. Hold on a second, I need to be precise here. It's not *any* user namespace, it's the *current* user namespace that needs `CAP_NET_ADMIN`. This is important for understanding the potential security boundary. Just to be absolutely sure, let's just double-check the definition of `GENL_UNS_ADMIN_PERM` and make sure my understanding is spot on. I'm going to quickly look at the code. I always double check assumptions in these cases.
|
| 15/2 |
2026/05/17 19:05 |
tool |
grepper |
0m
Args: map[Expression:GENL_UNS_ADMIN_PERM]
Results: map[Output:
Full output is too long, showing 500 out of 759 lines.
Use more precise expression if possible.
[drivers/net/ieee802154/mac802154_hwsim.c=751=static const struct genl_small_ops hwsim_nl_ops[] = {
--
drivers/net/ieee802154/mac802154_hwsim.c-755- .doit = hwsim_new_radio_nl,
drivers/net/ieee802154/mac802154_hwsim.c:756: .flags = GENL_UNS_ADMIN_PERM,
drivers/net/ieee802154/mac802154_hwsim.c-757- },
--
drivers/net/ieee802154/mac802154_hwsim.c-761- .doit = hwsim_del_radio_nl,
drivers/net/ieee802154/mac802154_hwsim.c:762: .flags = GENL_UNS_ADMIN_PERM,
drivers/net/ieee802154/mac802154_hwsim.c-763- },
--
drivers/net/ieee802154/mac802154_hwsim.c-773- .doit = hwsim_new_edge_nl,
drivers/net/ieee802154/mac802154_hwsim.c:774: .flags = GENL_UNS_ADMIN_PERM,
drivers/net/ieee802154/mac802154_hwsim.c-775- },
--
drivers/net/ieee802154/mac802154_hwsim.c-779- .doit = hwsim_del_edge_nl,
drivers/net/ieee802154/mac802154_hwsim.c:780: .flags = GENL_UNS_ADMIN_PERM,
drivers/net/ieee802154/mac802154_hwsim.c-781- },
--
drivers/net/ieee802154/mac802154_hwsim.c-785- .doit = hwsim_set_edge_lqi,
drivers/net/ieee802154/mac802154_hwsim.c:786: .flags = GENL_UNS_ADMIN_PERM,
drivers/net/ieee802154/mac802154_hwsim.c-787- },
--
drivers/net/wireguard/generated/netlink.c=56=const struct genl_split_ops wireguard_nl_ops[2] = {
--
drivers/net/wireguard/generated/netlink.c-63- .maxattr = WGDEVICE_A_IFNAME,
drivers/net/wireguard/generated/netlink.c:64: .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DUMP,
drivers/net/wireguard/generated/netlink.c-65- },
--
drivers/net/wireguard/generated/netlink.c-70- .maxattr = WGDEVICE_A_PEERS,
drivers/net/wireguard/generated/netlink.c:71: .flags = GENL_UNS_ADMIN_PERM | GENL_CMD_CAP_DO,
drivers/net/wireguard/generated/netlink.c-72- },
--
drivers/net/wireless/virtual/mac80211_hwsim.c=6874=static const struct genl_small_ops hwsim_ops[] = {
--
drivers/net/wireless/virtual/mac80211_hwsim.c-6878- .doit = hwsim_register_received_nl,
drivers/net/wireless/virtual/mac80211_hwsim.c:6879: .flags = GENL_UNS_ADMIN_PERM,
drivers/net/wireless/virtual/mac80211_hwsim.c-6880- },
--
drivers/net/wireless/virtual/mac80211_hwsim.c-6894- .doit = hwsim_new_radio_nl,
drivers/net/wireless/virtual/mac80211_hwsim.c:6895: .flags = GENL_UNS_ADMIN_PERM,
drivers/net/wireless/virtual/mac80211_hwsim.c-6896- },
--
drivers/net/wireless/virtual/mac80211_hwsim.c-6900- .doit = hwsim_del_radio_nl,
drivers/net/wireless/virtual/mac80211_hwsim.c:6901: .flags = GENL_UNS_ADMIN_PERM,
drivers/net/wireless/virtual/mac80211_hwsim.c-6902- },
--
include/net/genetlink.h=173=enum genl_validate_flags {
--
include/net/genetlink.h-182- * @internal_flags: flags used by the family
include/net/genetlink.h:183: * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
include/net/genetlink.h-184- * @validate: validation flags from enum genl_validate_flags
--
include/net/genetlink.h=191=struct genl_small_ops {
--
include/net/genetlink.h-203- * @internal_flags: flags used by the family
include/net/genetlink.h:204: * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
include/net/genetlink.h-205- * @maxattr: maximum number of attributes supported
--
include/net/genetlink.h=213=struct genl_ops {
--
include/net/genetlink.h-231- * @internal_flags: flags used by the family
include/net/genetlink.h:232: * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
include/net/genetlink.h-233- * @validate: validation flags from enum genl_validate_flags
--
include/uapi/linux/genetlink.h=13=struct genlmsghdr {
--
include/uapi/linux/genetlink.h-24-#define GENL_CMD_CAP_HASPOL 0x08
include/uapi/linux/genetlink.h:25:#define GENL_UNS_ADMIN_PERM 0x10
include/uapi/linux/genetlink.h-26-
--
net/batman-adv/netlink.c=1400=static const struct genl_small_ops batadv_netlink_ops[] = {
--
net/batman-adv/netlink.c-1410- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1411: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1412- .doit = batadv_netlink_tp_meter_start,
--
net/batman-adv/netlink.c-1417- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1418: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1419- .doit = batadv_netlink_tp_meter_cancel,
--
net/batman-adv/netlink.c-1424- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1425: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1426- .dumpit = batadv_algo_dump,
--
net/batman-adv/netlink.c-1439- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1440: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1441- .dumpit = batadv_tt_local_dump,
--
net/batman-adv/netlink.c-1445- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1446: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1447- .dumpit = batadv_tt_global_dump,
--
net/batman-adv/netlink.c-1451- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1452: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1453- .dumpit = batadv_orig_dump,
--
net/batman-adv/netlink.c-1457- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1458: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1459- .dumpit = batadv_hardif_neigh_dump,
--
net/batman-adv/netlink.c-1463- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1464: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1465- .dumpit = batadv_gw_dump,
--
net/batman-adv/netlink.c-1469- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1470: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1471- .dumpit = batadv_bla_claim_dump,
--
net/batman-adv/netlink.c-1475- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1476: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1477- .dumpit = batadv_bla_backbone_dump,
--
net/batman-adv/netlink.c-1481- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1482: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1483- .dumpit = batadv_dat_cache_dump,
--
net/batman-adv/netlink.c-1487- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1488: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1489- .dumpit = batadv_mcast_flags_dump,
--
net/batman-adv/netlink.c-1493- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1494: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1495- .doit = batadv_netlink_set_mesh,
--
net/batman-adv/netlink.c-1500- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1501: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1502- .doit = batadv_netlink_set_hardif,
--
net/batman-adv/netlink.c-1516- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/batman-adv/netlink.c:1517: .flags = GENL_UNS_ADMIN_PERM,
net/batman-adv/netlink.c-1518- .doit = batadv_netlink_set_vlan,
--
net/ethtool/netlink.c=1135=static const struct genl_ops ethtool_genl_ops[] = {
--
net/ethtool/netlink.c-1155- .cmd = ETHTOOL_MSG_LINKINFO_SET,
net/ethtool/netlink.c:1156: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1157- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1171- .cmd = ETHTOOL_MSG_LINKMODES_SET,
net/ethtool/netlink.c:1172: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1173- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1196- .cmd = ETHTOOL_MSG_DEBUG_SET,
net/ethtool/netlink.c:1197: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1198- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1203- .cmd = ETHTOOL_MSG_WOL_GET,
net/ethtool/netlink.c:1204: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1205- .doit = ethnl_default_doit,
--
net/ethtool/netlink.c-1213- .cmd = ETHTOOL_MSG_WOL_SET,
net/ethtool/netlink.c:1214: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1215- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1229- .cmd = ETHTOOL_MSG_FEATURES_SET,
net/ethtool/netlink.c:1230: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1231- .doit = ethnl_set_features,
--
net/ethtool/netlink.c-1245- .cmd = ETHTOOL_MSG_PRIVFLAGS_SET,
net/ethtool/netlink.c:1246: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1247- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1261- .cmd = ETHTOOL_MSG_RINGS_SET,
net/ethtool/netlink.c:1262: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1263- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1277- .cmd = ETHTOOL_MSG_CHANNELS_SET,
net/ethtool/netlink.c:1278: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1279- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1293- .cmd = ETHTOOL_MSG_COALESCE_SET,
net/ethtool/netlink.c:1294: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1295- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1309- .cmd = ETHTOOL_MSG_PAUSE_SET,
net/ethtool/netlink.c:1310: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1311- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1325- .cmd = ETHTOOL_MSG_EEE_SET,
net/ethtool/netlink.c:1326: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1327- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1341- .cmd = ETHTOOL_MSG_CABLE_TEST_ACT,
net/ethtool/netlink.c:1342: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1343- .doit = ethnl_act_cable_test,
--
net/ethtool/netlink.c-1348- .cmd = ETHTOOL_MSG_CABLE_TEST_TDR_ACT,
net/ethtool/netlink.c:1349: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1350- .doit = ethnl_act_cable_test_tdr,
--
net/ethtool/netlink.c-1372- .cmd = ETHTOOL_MSG_FEC_SET,
net/ethtool/netlink.c:1373: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1374- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1379- .cmd = ETHTOOL_MSG_MODULE_EEPROM_GET,
net/ethtool/netlink.c:1380: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1381- .doit = ethnl_default_doit,
--
net/ethtool/netlink.c-1416- .cmd = ETHTOOL_MSG_MODULE_SET,
net/ethtool/netlink.c:1417: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1418- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1432- .cmd = ETHTOOL_MSG_PSE_SET,
net/ethtool/netlink.c:1433: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1434- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1456- .cmd = ETHTOOL_MSG_PLCA_SET_CFG,
net/ethtool/netlink.c:1457: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1458- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1481- .cmd = ETHTOOL_MSG_MM_SET,
net/ethtool/netlink.c:1482: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1483- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1488- .cmd = ETHTOOL_MSG_MODULE_FW_FLASH_ACT,
net/ethtool/netlink.c:1489: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1490- .doit = ethnl_act_module_fw_flash,
--
net/ethtool/netlink.c-1513- .cmd = ETHTOOL_MSG_TSCONFIG_SET,
net/ethtool/netlink.c:1514: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1515- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1520- .cmd = ETHTOOL_MSG_RSS_SET,
net/ethtool/netlink.c:1521: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1522- .doit = ethnl_default_set_doit,
--
net/ethtool/netlink.c-1527- .cmd = ETHTOOL_MSG_RSS_CREATE_ACT,
net/ethtool/netlink.c:1528: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1529- .doit = ethnl_rss_create_doit,
--
net/ethtool/netlink.c-1534- .cmd = ETHTOOL_MSG_RSS_DELETE_ACT,
net/ethtool/netlink.c:1535: .flags = GENL_UNS_ADMIN_PERM,
net/ethtool/netlink.c-1536- .doit = ethnl_rss_delete_doit,
--
net/l2tp/l2tp_netlink.c=935=static const struct genl_small_ops l2tp_nl_ops[] = {
--
net/l2tp/l2tp_netlink.c-945- .doit = l2tp_nl_cmd_tunnel_create,
net/l2tp/l2tp_netlink.c:946: .flags = GENL_UNS_ADMIN_PERM,
net/l2tp/l2tp_netlink.c-947- },
--
net/l2tp/l2tp_netlink.c-951- .doit = l2tp_nl_cmd_tunnel_delete,
net/l2tp/l2tp_netlink.c:952: .flags = GENL_UNS_ADMIN_PERM,
net/l2tp/l2tp_netlink.c-953- },
--
net/l2tp/l2tp_netlink.c-957- .doit = l2tp_nl_cmd_tunnel_modify,
net/l2tp/l2tp_netlink.c:958: .flags = GENL_UNS_ADMIN_PERM,
net/l2tp/l2tp_netlink.c-959- },
--
net/l2tp/l2tp_netlink.c-964- .dumpit = l2tp_nl_cmd_tunnel_dump,
net/l2tp/l2tp_netlink.c:965: .flags = GENL_UNS_ADMIN_PERM,
net/l2tp/l2tp_netlink.c-966- },
--
net/l2tp/l2tp_netlink.c-970- .doit = l2tp_nl_cmd_session_create,
net/l2tp/l2tp_netlink.c:971: .flags = GENL_UNS_ADMIN_PERM,
net/l2tp/l2tp_netlink.c-972- },
--
net/l2tp/l2tp_netlink.c-976- .doit = l2tp_nl_cmd_session_delete,
net/l2tp/l2tp_netlink.c:977: .flags = GENL_UNS_ADMIN_PERM,
net/l2tp/l2tp_netlink.c-978- },
--
net/l2tp/l2tp_netlink.c-982- .doit = l2tp_nl_cmd_session_modify,
net/l2tp/l2tp_netlink.c:983: .flags = GENL_UNS_ADMIN_PERM,
net/l2tp/l2tp_netlink.c-984- },
--
net/l2tp/l2tp_netlink.c-989- .dumpit = l2tp_nl_cmd_session_dump,
net/l2tp/l2tp_netlink.c:990: .flags = GENL_UNS_ADMIN_PERM,
net/l2tp/l2tp_netlink.c-991- },
--
net/mptcp/mptcp_pm_gen.c=92=const struct genl_ops mptcp_pm_nl_ops[11] = {
--
net/mptcp/mptcp_pm_gen.c-98- .maxattr = MPTCP_PM_ENDPOINT_ADDR,
net/mptcp/mptcp_pm_gen.c:99: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-100- },
--
net/mptcp/mptcp_pm_gen.c-106- .maxattr = MPTCP_PM_ENDPOINT_ADDR,
net/mptcp/mptcp_pm_gen.c:107: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-108- },
--
net/mptcp/mptcp_pm_gen.c-122- .maxattr = MPTCP_PM_ENDPOINT_ADDR,
net/mptcp/mptcp_pm_gen.c:123: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-124- },
--
net/mptcp/mptcp_pm_gen.c-130- .maxattr = MPTCP_PM_ATTR_SUBFLOWS,
net/mptcp/mptcp_pm_gen.c:131: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-132- },
--
net/mptcp/mptcp_pm_gen.c-145- .maxattr = MPTCP_PM_ATTR_ADDR_REMOTE,
net/mptcp/mptcp_pm_gen.c:146: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-147- },
--
net/mptcp/mptcp_pm_gen.c-153- .maxattr = MPTCP_PM_ATTR_TOKEN,
net/mptcp/mptcp_pm_gen.c:154: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-155- },
--
net/mptcp/mptcp_pm_gen.c-161- .maxattr = MPTCP_PM_ATTR_LOC_ID,
net/mptcp/mptcp_pm_gen.c:162: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-163- },
--
net/mptcp/mptcp_pm_gen.c-169- .maxattr = MPTCP_PM_ATTR_ADDR_REMOTE,
net/mptcp/mptcp_pm_gen.c:170: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-171- },
--
net/mptcp/mptcp_pm_gen.c-177- .maxattr = MPTCP_PM_ATTR_ADDR_REMOTE,
net/mptcp/mptcp_pm_gen.c:178: .flags = GENL_UNS_ADMIN_PERM,
net/mptcp/mptcp_pm_gen.c-179- },
--
net/netlink/genetlink.c=1155=static int genl_family_rcv_msg(const struct genl_family *family,
--
net/netlink/genetlink.c-1185-
net/netlink/genetlink.c:1186: if ((op.flags & GENL_UNS_ADMIN_PERM) &&
net/netlink/genetlink.c-1187- !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
--
net/openvswitch/conntrack.c=1956=static const struct genl_small_ops ct_limit_genl_ops[] = {
--
net/openvswitch/conntrack.c-1958- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/conntrack.c:1959: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN
net/openvswitch/conntrack.c-1960- * privilege.
--
net/openvswitch/conntrack.c-1965- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/conntrack.c:1966: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN
net/openvswitch/conntrack.c-1967- * privilege.
--
net/openvswitch/datapath.c=730=static const struct genl_small_ops dp_packet_genl_ops[] = {
--
net/openvswitch/datapath.c-732- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:733: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-734- .doit = ovs_packet_cmd_execute
--
net/openvswitch/datapath.c=1539=static const struct genl_small_ops dp_flow_genl_ops[] = {
--
net/openvswitch/datapath.c-1541- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:1542: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-1543- .doit = ovs_flow_cmd_new
--
net/openvswitch/datapath.c-1546- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:1547: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-1548- .doit = ovs_flow_cmd_del
--
net/openvswitch/datapath.c-1557- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:1558: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-1559- .doit = ovs_flow_cmd_set,
--
net/openvswitch/datapath.c=2085=static const struct genl_small_ops dp_datapath_genl_ops[] = {
--
net/openvswitch/datapath.c-2087- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:2088: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-2089- .doit = ovs_dp_cmd_new
--
net/openvswitch/datapath.c-2092- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:2093: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-2094- .doit = ovs_dp_cmd_del
--
net/openvswitch/datapath.c-2103- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:2104: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-2105- .doit = ovs_dp_cmd_set,
--
net/openvswitch/datapath.c=2582=static const struct genl_small_ops dp_vport_genl_ops[] = {
--
net/openvswitch/datapath.c-2584- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:2585: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-2586- .doit = ovs_vport_cmd_new
--
net/openvswitch/datapath.c-2589- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:2590: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-2591- .doit = ovs_vport_cmd_del
--
net/openvswitch/datapath.c-2600- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/datapath.c:2601: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
net/openvswitch/datapath.c-2602- .doit = ovs_vport_cmd_set,
--
net/openvswitch/meter.c=682=static const struct genl_small_ops dp_meter_genl_ops[] = {
--
net/openvswitch/meter.c-689- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/meter.c:690: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN
net/openvswitch/meter.c-691- * privilege.
--
net/openvswitch/meter.c-701- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/openvswitch/meter.c:702: .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN
net/openvswitch/meter.c-703- * privilege.
--
net/wireless/nl80211.c=19120=static const struct genl_small_ops nl80211_small_ops[] = {
--
net/wireless/nl80211.c-19124- .doit = nl80211_set_wiphy,
net/wireless/nl80211.c:19125: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19126- },
--
net/wireless/nl80211.c-19138- .doit = nl80211_set_interface,
net/wireless/nl80211.c:19139: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19140- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
--
net/wireless/nl80211.c-19146- .doit = nl80211_new_interface,
net/wireless/nl80211.c:19147: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19148- .internal_flags =
--
net/wireless/nl80211.c-19157- .doit = nl80211_del_interface,
net/wireless/nl80211.c:19158: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19159- .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV |
--
net/wireless/nl80211.c-19165- .doit = nl80211_get_key,
net/wireless/nl80211.c:19166: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19167- .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
--
net/wireless/nl80211.c-19172- .doit = nl80211_set_key,
net/wireless/nl80211.c:19173: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19174- /* cannot use NL80211_FLAG_MLO_VALID_LINK_ID, depends on key */
--
net/wireless/nl80211.c-19181- .doit = nl80211_new_key,
net/wireless/nl80211.c:19182: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19183- .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
--
net/wireless/nl80211.c-19189- .doit = nl80211_del_key,
net/wireless/nl80211.c:19190: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19191- .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
--
net/wireless/nl80211.c-19195- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/wireless/nl80211.c:19196: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19197- .doit = nl80211_set_beacon,
--
net/wireless/nl80211.c-19203- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/wireless/nl80211.c:19204: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19205- .doit = nl80211_start_ap,
--
net/wireless/nl80211.c-19211- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
net/wireless/nl80211.c:19212: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19213- .doit = nl80211_stop_ap,
--
net/wireless/nl80211.c-19227- .doit = nl80211_set_station,
net/wireless/nl80211.c:19228: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19229- .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
--
net/wireless/nl80211.c-19234- .doit = nl80211_new_station,
net/wireless/nl80211.c:19235: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19236- .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
--
net/wireless/nl80211.c-19241- .doit = nl80211_del_station,
net/wireless/nl80211.c:19242: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19243- /* cannot use NL80211_FLAG_MLO_VALID_LINK_ID, depends on
--
net/wireless/nl80211.c-19253- .dumpit = nl80211_dump_mpath,
net/wireless/nl80211.c:19254: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19255- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19261- .dumpit = nl80211_dump_mpp,
net/wireless/nl80211.c:19262: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19263- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19268- .doit = nl80211_set_mpath,
net/wireless/nl80211.c:19269: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19270- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19275- .doit = nl80211_new_mpath,
net/wireless/nl80211.c:19276: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19277- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19282- .doit = nl80211_del_mpath,
net/wireless/nl80211.c:19283: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19284- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19289- .doit = nl80211_set_bss,
net/wireless/nl80211.c:19290: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19291- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
--
net/wireless/nl80211.c-19331- .doit = nl80211_update_mesh_config,
net/wireless/nl80211.c:19332: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19333- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19338- .doit = nl80211_trigger_scan,
net/wireless/nl80211.c:19339: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19340- .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
--
net/wireless/nl80211.c-19345- .doit = nl80211_abort_scan,
net/wireless/nl80211.c:19346: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19347- .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
--
net/wireless/nl80211.c-19357- .doit = nl80211_start_sched_scan,
net/wireless/nl80211.c:19358: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19359- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19364- .doit = nl80211_stop_sched_scan,
net/wireless/nl80211.c:19365: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19366- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19371- .doit = nl80211_authenticate,
net/wireless/nl80211.c:19372: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19373- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
--
net/wireless/nl80211.c-19379- .doit = nl80211_associate,
net/wireless/nl80211.c:19380: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19381- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
--
net/wireless/nl80211.c-19387- .doit = nl80211_deauthenticate,
net/wireless/nl80211.c:19388: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19389- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19394- .doit = nl80211_disassociate,
net/wireless/nl80211.c:19395: .flags = GENL_UNS_ADMIN_PERM,
net/wireless/nl80211.c-19396- .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
--
net/wireless/nl80211.c-19401- .doit = nl80211_join_ibss,
net/wireless/nl80211.c:19402: .flags = GENL_UNS_ADMIN_PERM,
]
]
|
| 16/2 |
2026/05/17 19:05 |
llm |
expert |
0m
Model:
Tokens:
input: 38039
output: 48
thoughts: 55
Thoughts: Okay, let me think this through.
**Analyzing the Permission Requirements**
Hold on a second, that `GENL_UNS_ADMIN_PERM` flag... that's a key piece of information. That's a strong indicator that this operation is going to need `CAP_NET_ADMIN` within the user namespace. I need to be absolutely sure about this, so I need to dig into the details. Time to check the implementation of `netlink_ns_capable` in `net/netlink/genetlink.c`. I need to understand how the system is actually handling this capability check. This is where the rubber meets the road.
|
| 17/2 |
2026/05/17 19:05 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/netlink/genetlink.c IncludeLines:true Name:genl_family_rcv_msg]
Results: map[SourceCode:1155: static int genl_family_rcv_msg(const struct genl_family *family,
1156: struct sk_buff *skb,
1157: struct nlmsghdr *nlh,
1158: struct netlink_ext_ack *extack)
1159: {
1160: struct net *net = sock_net(skb->sk);
1161: struct genlmsghdr *hdr = nlmsg_data(nlh);
1162: struct genl_split_ops op;
1163: int hdrlen;
1164: u8 flags;
1165:
1166: /* this family doesn't exist in this netns */
1167: if (!family->netnsok && !net_eq(net, &init_net))
1168: return -ENOENT;
1169:
1170: hdrlen = GENL_HDRLEN + family->hdrsize;
1171: if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
1172: return -EINVAL;
1173:
1174: if (genl_header_check(family, nlh, hdr, extack))
1175: return -EINVAL;
1176:
1177: flags = (nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP ?
1178: GENL_CMD_CAP_DUMP : GENL_CMD_CAP_DO;
1179: if (genl_get_cmd(hdr->cmd, flags, family, &op))
1180: return -EOPNOTSUPP;
1181:
1182: if ((op.flags & GENL_ADMIN_PERM) &&
1183: !netlink_capable(skb, CAP_NET_ADMIN))
1184: return -EPERM;
1185:
1186: if ((op.flags & GENL_UNS_ADMIN_PERM) &&
1187: !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
1188: return -EPERM;
1189:
1190: if (flags & GENL_CMD_CAP_DUMP)
1191: return genl_family_rcv_msg_dumpit(family, skb, nlh, extack,
1192: &op, hdrlen, net);
1193: else
1194: return genl_family_rcv_msg_doit(family, skb, nlh, extack,
1195: &op, hdrlen, net);
1196: }
SourceFile:net/netlink/genetlink.c]
|
| 18/2 |
2026/05/17 19:05 |
llm |
expert |
0m
Model:
Tokens:
input: 39052
output: 59
thoughts: 613
Thoughts: **Analyzing the HWSIM Kernel Module Vulnerability**
Okay, so I'm digging into this `HWSIM` kernel module. I'm seeing this `netlink_ns_capable` check, and it's looking for `CAP_NET_ADMIN` in the network namespace's user namespace. If a process creates both a new user and network namespace, it would naturally have this capability. The presence of `GENL_UNS_ADMIN_PERM` makes sense, allowing access from a user namespace that has admin privileges, but `HWSIM_CMD_FRAME` *doesn't* have `GENL_UNS_ADMIN_PERM` or `GENL_ADMIN_PERM`.
Let's revisit `hwsim_ops` to confirm this. Yep, it's there:
```c
{
.cmd = HWSIM_CMD_FRAME,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = hwsim_cloned_frame_received_nl,
},
```
So, no permission flags. This immediately raises a red flag; `HWSIM_CMD_FRAME` seems to be accessible to unprivileged processes, which is concerning. I need to be sure.
But then I see the reproducer. It's using:
```c
int hwsim_family_id = netlink_query_family_id(&tmp_msg, sock, "MAC80211_HWSIM", false);
int ret = hwsim_register_socket(&tmp_msg, sock, hwsim_family_id);
ret = hwsim_inject_frame(&tmp_msg, sock, hwsim_family_id, mac_addr, buf, buf_len);
```
Ah, `hwsim_register_socket` uses `HWSIM_CMD_REGISTER`, which *does* have `.flags = GENL_UNS_ADMIN_PERM`. So to register a socket, one does need `CAP_NET_ADMIN` in the user namespace, like I thought initially.
But the reproducer is running as root (UID: 0). Now, can an unprivileged process trigger this? If `HWSIM_CMD_REGISTER` demands `CAP_NET_ADMIN`, then an unprivileged process cannot call it directly. It would need to first create a user namespace.
Now, wait a minute, the prompt *specifically* says that user namespaces aren't accessible. So, if `HWSIM_CMD_REGISTER` requires this capability in a user namespace, then it's effectively inaccessible from unprivileged processes, as dictated by the prompt.
Now, the critical question: Does `HWSIM_CMD_FRAME` *depend* on the socket being registered? That's the linchpin. I need to check `hwsim_cloned_frame_received_nl` to be sure. This is where the vulnerability lies if it is independent.
|
| 19/2 |
2026/05/17 19:05 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:hwsim_cloned_frame_received_nl]
Results: map[SourceCode:6335: static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
6336: struct genl_info *info)
6337: {
6338: struct mac80211_hwsim_data *data2;
6339: struct ieee80211_rx_status rx_status;
6340: struct ieee80211_hdr *hdr;
6341: const u8 *dst;
6342: int frame_data_len;
6343: void *frame_data;
6344: struct sk_buff *skb = NULL;
6345: struct ieee80211_channel *channel = NULL;
6346:
6347: if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
6348: !info->attrs[HWSIM_ATTR_FRAME] ||
6349: !info->attrs[HWSIM_ATTR_RX_RATE] ||
6350: !info->attrs[HWSIM_ATTR_SIGNAL])
6351: goto out;
6352:
6353: dst = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_RECEIVER]);
6354: frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]);
6355: frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
6356:
6357: if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) ||
6358: frame_data_len > IEEE80211_MAX_DATA_LEN)
6359: goto err;
6360:
6361: /* Allocate new skb here */
6362: skb = alloc_skb(frame_data_len, GFP_KERNEL);
6363: if (skb == NULL)
6364: goto err;
6365:
6366: /* Copy the data */
6367: skb_put_data(skb, frame_data, frame_data_len);
6368:
6369: data2 = get_hwsim_data_ref_from_addr(dst);
6370: if (!data2)
6371: goto out;
6372:
6373: if (data2->use_chanctx) {
6374: if (data2->tmp_chan)
6375: channel = data2->tmp_chan;
6376: } else {
6377: channel = data2->channel;
6378: }
6379:
6380: if (!hwsim_virtio_enabled) {
6381: if (hwsim_net_get_netgroup(genl_info_net(info)) !=
6382: data2->netgroup)
6383: goto out;
6384:
6385: if (info->snd_portid != data2->wmediumd)
6386: goto out;
6387: }
6388:
6389: /* check if radio is configured properly */
6390:
6391: if ((data2->idle && !data2->tmp_chan) || !data2->started)
6392: goto out;
6393:
6394: /* A frame is received from user space */
6395: memset(&rx_status, 0, sizeof(rx_status));
6396: if (info->attrs[HWSIM_ATTR_FREQ]) {
6397: struct tx_iter_data iter_data = {};
6398:
6399: /* throw away off-channel packets, but allow both the temporary
6400: * ("hw" scan/remain-on-channel), regular channels and links,
6401: * since the internal datapath also allows this
6402: */
6403: rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
6404:
6405: iter_data.channel = ieee80211_get_channel(data2->hw->wiphy,
6406: rx_status.freq);
6407: if (!iter_data.channel)
6408: goto out;
6409: rx_status.band = iter_data.channel->band;
6410:
6411: mutex_lock(&data2->mutex);
6412: if (!hwsim_chans_compat(iter_data.channel, channel)) {
6413: ieee80211_iterate_active_interfaces_atomic(
6414: data2->hw, IEEE80211_IFACE_ITER_NORMAL,
6415: mac80211_hwsim_tx_iter, &iter_data);
6416: if (!iter_data.receive) {
6417: mutex_unlock(&data2->mutex);
6418: goto out;
6419: }
6420: }
6421: mutex_unlock(&data2->mutex);
6422: } else if (!channel) {
6423: goto out;
6424: } else {
6425: rx_status.freq = channel->center_freq;
6426: rx_status.band = channel->band;
6427: }
6428:
6429: rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
6430: if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
6431: goto out;
6432: rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
6433:
6434: hdr = (void *)skb->data;
6435:
6436: if (ieee80211_is_beacon(hdr->frame_control) ||
6437: ieee80211_is_probe_resp(hdr->frame_control))
6438: rx_status.boottime_ns = ktime_get_boottime_ns();
6439:
6440: mac80211_hwsim_rx(data2, &rx_status, skb);
6441:
6442: return 0;
6443: err:
6444: pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
6445: out:
6446: dev_kfree_skb(skb);
6447: return -EINVAL;
6448: }
SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c]
|
| 20/2 |
2026/05/17 19:05 |
llm |
expert |
0m
Model:
Tokens:
input: 42315
output: 55
thoughts: 402
Thoughts: **Analyzing the HWSIM Frame Reception Checks**
Okay, so I'm looking at the `hwsim_cloned_frame_received_nl` function and the checks within it. The key lines here are the `if` statements. I see that there's a check that seems to be related to network groups and the sender's port ID (`info->snd_portid`). Specifically, the code compares `info->snd_portid` to `data2->wmediumd`. It looks like `data2->wmediumd` is set during a socket registration using `HWSIM_CMD_REGISTER`.
Now, I need to understand how this relates to the reproducer I'm working with. Let's see... the reproducer calls `hwsim_register_socket` and then attempts to inject a frame using `hwsim_inject_frame`. The reproducer uses `syz_80211_inject_frame`. If `hwsim_register_socket` fails, the whole process returns an error. This means the socket isn't registered.
Here's where it gets interesting: Successful registration, meaning `hwsim_register_socket` doesn't fail, implies that the process *has* `CAP_NET_ADMIN` in its user namespace. And since the reproducer is running as root, it starts with `CAP_NET_ADMIN` in the initial user namespace. Therefore, in the expected initial setup, an unprivileged process can't trigger the checks. It can't register a socket and therefore can't get past the `info->snd_portid != data2->wmediumd` check. This would mean that an unprivileged process cannot inject frames via `HWSIM_CMD_FRAME`.
But wait... there's a global variable, `hwsim_virtio_enabled`. If this variable is true, those checks are completely bypassed. This seems like a crucial oversight. I need to investigate the state of `hwsim_virtio_enabled` and whether or how it could be set to true.
|
| 21/2 |
2026/05/17 19:05 |
tool |
codesearch-definition-source |
0m
Error:
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:hwsim_virtio_enabled]
Results: map[SourceCode: SourceFile:]
|
| 22/2 |
2026/05/17 19:05 |
llm |
expert |
0m
Model:
Tokens:
input: 43232
output: 21
thoughts: 28
Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue:
**Investigating `hwsim_virtio_enabled` in mac80211_hwsim.c**
Alright, time to get to the bottom of this. My first instinct is to zero in on `hwsim_virtio_enabled`. Given its name, I'm guessing this flag likely has something to do with enabling or configuring virtio support within the mac80211 hardware simulator â `mac80211_hwsim.c`. The fact that it's flagged as potentially relevant suggests it's likely a recent addition or a feature I haven't needed to directly interact with yet. Let's see what we can dig up within that specific file. My bet is it'll be a macro, a static variable, or perhaps even a function that controls some aspect of the virtio interface within the simulated wireless environment. Let's dive into the code and see what we find.
|
| 23/2 |
2026/05/17 19:05 |
tool |
grepper |
0m
Args: map[Expression:hwsim_virtio_enabled]
Results: map[Output:drivers/net/wireless/virtual/mac80211_hwsim.c=950=static struct virtqueue *hwsim_vqs[HWSIM_NUM_VQS];
drivers/net/wireless/virtual/mac80211_hwsim.c:951:static bool hwsim_virtio_enabled;
drivers/net/wireless/virtual/mac80211_hwsim.c-952-static DEFINE_SPINLOCK(hwsim_virtio_lock);
--
drivers/net/wireless/virtual/mac80211_hwsim.c=957=static int hwsim_tx_virtio(struct mac80211_hwsim_data *data,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-964- spin_lock_irqsave(&hwsim_virtio_lock, flags);
drivers/net/wireless/virtual/mac80211_hwsim.c:965: if (!hwsim_virtio_enabled) {
drivers/net/wireless/virtual/mac80211_hwsim.c-966- err = -ENODEV;
--
drivers/net/wireless/virtual/mac80211_hwsim.c=986=extern int hwsim_tx_virtio(struct mac80211_hwsim_data *data,
drivers/net/wireless/virtual/mac80211_hwsim.c-987- struct sk_buff *skb);
drivers/net/wireless/virtual/mac80211_hwsim.c:988:#define hwsim_virtio_enabled false
drivers/net/wireless/virtual/mac80211_hwsim.c-989-#endif
--
drivers/net/wireless/virtual/mac80211_hwsim.c=1552=static void mac80211_hwsim_config_mac_nl(struct ieee80211_hw *hw,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-1561-
drivers/net/wireless/virtual/mac80211_hwsim.c:1562: if (!_portid && !hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-1563- return;
--
drivers/net/wireless/virtual/mac80211_hwsim.c-1585-
drivers/net/wireless/virtual/mac80211_hwsim.c:1586: if (hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-1587- hwsim_tx_virtio(data, skb);
--
drivers/net/wireless/virtual/mac80211_hwsim.c=1625=static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-1714-
drivers/net/wireless/virtual/mac80211_hwsim.c:1715: if (hwsim_virtio_enabled) {
drivers/net/wireless/virtual/mac80211_hwsim.c-1716- if (hwsim_tx_virtio(data, skb))
--
drivers/net/wireless/virtual/mac80211_hwsim.c=2077=static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-2262-
drivers/net/wireless/virtual/mac80211_hwsim.c:2263: if (_portid || hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-2264- return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, channel);
--
drivers/net/wireless/virtual/mac80211_hwsim.c=2379=static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-2394-
drivers/net/wireless/virtual/mac80211_hwsim.c:2395: if (_portid || hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-2396- return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, chan);
--
drivers/net/wireless/virtual/mac80211_hwsim.c=3708=static int mac80211_hwsim_start_pmsr(struct ieee80211_hw *hw,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-3720- _portid = READ_ONCE(data->wmediumd);
drivers/net/wireless/virtual/mac80211_hwsim.c:3721: if (!_portid && !hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-3722- return -EOPNOTSUPP;
--
drivers/net/wireless/virtual/mac80211_hwsim.c-3758- genlmsg_end(skb, msg_head);
drivers/net/wireless/virtual/mac80211_hwsim.c:3759: if (hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-3760- hwsim_tx_virtio(data, skb);
--
drivers/net/wireless/virtual/mac80211_hwsim.c=3775=static void mac80211_hwsim_abort_pmsr(struct ieee80211_hw *hw,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-3787- _portid = READ_ONCE(data->wmediumd);
drivers/net/wireless/virtual/mac80211_hwsim.c:3788: if (!_portid && !hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-3789- return;
--
drivers/net/wireless/virtual/mac80211_hwsim.c-3823- genlmsg_end(skb, msg_head);
drivers/net/wireless/virtual/mac80211_hwsim.c:3824: if (hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-3825- hwsim_tx_virtio(data, skb);
--
drivers/net/wireless/virtual/mac80211_hwsim.c=6237=static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-6267-
drivers/net/wireless/virtual/mac80211_hwsim.c:6268: if (!hwsim_virtio_enabled) {
drivers/net/wireless/virtual/mac80211_hwsim.c-6269- if (hwsim_net_get_netgroup(genl_info_net(info)) !=
--
drivers/net/wireless/virtual/mac80211_hwsim.c=6335=static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
--
drivers/net/wireless/virtual/mac80211_hwsim.c-6379-
drivers/net/wireless/virtual/mac80211_hwsim.c:6380: if (!hwsim_virtio_enabled) {
drivers/net/wireless/virtual/mac80211_hwsim.c-6381- if (hwsim_net_get_netgroup(genl_info_net(info)) !=
--
drivers/net/wireless/virtual/mac80211_hwsim.c=7105=static void hwsim_virtio_rx_work(struct work_struct *work)
--
drivers/net/wireless/virtual/mac80211_hwsim.c-7114- spin_lock_irqsave(&hwsim_virtio_lock, flags);
drivers/net/wireless/virtual/mac80211_hwsim.c:7115: if (!hwsim_virtio_enabled)
drivers/net/wireless/virtual/mac80211_hwsim.c-7116- goto out_unlock;
--
drivers/net/wireless/virtual/mac80211_hwsim.c-7128- spin_lock_irqsave(&hwsim_virtio_lock, flags);
drivers/net/wireless/virtual/mac80211_hwsim.c:7129: if (!hwsim_virtio_enabled) {
drivers/net/wireless/virtual/mac80211_hwsim.c-7130- dev_kfree_skb_irq(skb);
--
drivers/net/wireless/virtual/mac80211_hwsim.c=7201=static int hwsim_virtio_probe(struct virtio_device *vdev)
--
drivers/net/wireless/virtual/mac80211_hwsim.c-7206- spin_lock_irqsave(&hwsim_virtio_lock, flags);
drivers/net/wireless/virtual/mac80211_hwsim.c:7207: if (hwsim_virtio_enabled) {
drivers/net/wireless/virtual/mac80211_hwsim.c-7208- spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
--
drivers/net/wireless/virtual/mac80211_hwsim.c-7223- spin_lock_irqsave(&hwsim_virtio_lock, flags);
drivers/net/wireless/virtual/mac80211_hwsim.c:7224: hwsim_virtio_enabled = true;
drivers/net/wireless/virtual/mac80211_hwsim.c-7225- spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
--
drivers/net/wireless/virtual/mac80211_hwsim.c=7235=static void hwsim_virtio_remove(struct virtio_device *vdev)
drivers/net/wireless/virtual/mac80211_hwsim.c-7236-{
drivers/net/wireless/virtual/mac80211_hwsim.c:7237: hwsim_virtio_enabled = false;
drivers/net/wireless/virtual/mac80211_hwsim.c-7238-
]
|
| 24/2 |
2026/05/17 19:05 |
llm |
expert |
0m
Model:
Tokens:
input: 46387
output: 51
thoughts: 1017
Thoughts: **Analyzing the Security Implications of mac80211-hwsim in a KVM Guest**
Okay, let's break this down. My initial thought was that an unprivileged process *couldn't* inject frames via `HWSIM_CMD_FRAME` because it seemed to require `hwsim_virtio_enabled` being true, which, in turn, appeared to be linked to the `VIRTIO_ID_MAC80211_HWSIM` virtio device. The logic involved `info->snd_portid == data2->wmediumd` check. The latter, `data2->wmediumd`, is set by `hwsim_register_received_nl`, which handles `HWSIM_CMD_REGISTER`. And that command needs `CAP_NET_ADMIN` in the user namespace, making it privileged. I was also briefly concerned that a portid of zero could bypass that check, but quickly dismissed that possibility since netlink port IDs are non-zero in userspace. That, along with the other check for an unprivileged sender, would prevent the injection.
But the prompt asks about KVM guests. Then I saw `mac80211_hwsim` has a virtio *driver*! The key lies in whether the *host* exposes a `VIRTIO_ID_MAC80211_HWSIM` device to the guest. My experience suggests that's *not* a standard QEMU default. This ID, `VIRTIO_ID_MAC80211_HWSIM` is 29, so it's a specific device used for this simulation.
Then I recalled that this bug is in `mac80211_hwsim.c` which is a simulated radio. Is it even loaded by default? Usually, it's a module (`CONFIG_MAC80211_HWSIM=m`). If loaded, it creates simulated radios. So if the host doesn't expose this virtio device, the guest wouldn't be able to use the simulated radios.
But then I looked at the reproducer, which calls `syz_80211_inject_frame` using `HWSIM_CMD_FRAME`. But it *also* uses `NL80211_CMD_SET_INTERFACE` and `NL80211_CMD_JOIN_OCB`. These are `nl80211` commands. The important point now is to check if these commands require `CAP_NET_ADMIN` to be used. If so, a standard KVM guest setup may not be affected, since a typical unprivileged guest doesn't get this privilege.
|
| 25/2 |
2026/05/17 19:06 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/wireless/nl80211.c IncludeLines:true Name:nl80211_small_ops]
Results: map[SourceCode:19120: static const struct genl_small_ops nl80211_small_ops[] = {
19121: {
19122: .cmd = NL80211_CMD_SET_WIPHY,
19123: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19124: .doit = nl80211_set_wiphy,
19125: .flags = GENL_UNS_ADMIN_PERM,
19126: },
19127: {
19128: .cmd = NL80211_CMD_GET_INTERFACE,
19129: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19130: .doit = nl80211_get_interface,
19131: .dumpit = nl80211_dump_interface,
19132: /* can be retrieved by unprivileged users */
19133: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV),
19134: },
19135: {
19136: .cmd = NL80211_CMD_SET_INTERFACE,
19137: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19138: .doit = nl80211_set_interface,
19139: .flags = GENL_UNS_ADMIN_PERM,
19140: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
19141: NL80211_FLAG_NEED_RTNL),
19142: },
19143: {
19144: .cmd = NL80211_CMD_NEW_INTERFACE,
19145: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19146: .doit = nl80211_new_interface,
19147: .flags = GENL_UNS_ADMIN_PERM,
19148: .internal_flags =
19149: IFLAGS(NL80211_FLAG_NEED_WIPHY |
19150: NL80211_FLAG_NEED_RTNL |
19151: /* we take the wiphy mutex later ourselves */
19152: NL80211_FLAG_NO_WIPHY_MTX),
19153: },
19154: {
19155: .cmd = NL80211_CMD_DEL_INTERFACE,
19156: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19157: .doit = nl80211_del_interface,
19158: .flags = GENL_UNS_ADMIN_PERM,
19159: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV |
19160: NL80211_FLAG_NEED_RTNL),
19161: },
19162: {
19163: .cmd = NL80211_CMD_GET_KEY,
19164: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19165: .doit = nl80211_get_key,
19166: .flags = GENL_UNS_ADMIN_PERM,
19167: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19168: },
19169: {
19170: .cmd = NL80211_CMD_SET_KEY,
19171: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19172: .doit = nl80211_set_key,
19173: .flags = GENL_UNS_ADMIN_PERM,
19174: /* cannot use NL80211_FLAG_MLO_VALID_LINK_ID, depends on key */
19175: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
19176: NL80211_FLAG_CLEAR_SKB),
19177: },
19178: {
19179: .cmd = NL80211_CMD_NEW_KEY,
19180: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19181: .doit = nl80211_new_key,
19182: .flags = GENL_UNS_ADMIN_PERM,
19183: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
19184: NL80211_FLAG_CLEAR_SKB),
19185: },
19186: {
19187: .cmd = NL80211_CMD_DEL_KEY,
19188: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19189: .doit = nl80211_del_key,
19190: .flags = GENL_UNS_ADMIN_PERM,
19191: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19192: },
19193: {
19194: .cmd = NL80211_CMD_SET_BEACON,
19195: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19196: .flags = GENL_UNS_ADMIN_PERM,
19197: .doit = nl80211_set_beacon,
19198: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19199: NL80211_FLAG_MLO_VALID_LINK_ID),
19200: },
19201: {
19202: .cmd = NL80211_CMD_START_AP,
19203: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19204: .flags = GENL_UNS_ADMIN_PERM,
19205: .doit = nl80211_start_ap,
19206: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19207: NL80211_FLAG_MLO_VALID_LINK_ID),
19208: },
19209: {
19210: .cmd = NL80211_CMD_STOP_AP,
19211: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19212: .flags = GENL_UNS_ADMIN_PERM,
19213: .doit = nl80211_stop_ap,
19214: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19215: NL80211_FLAG_MLO_VALID_LINK_ID),
19216: },
19217: {
19218: .cmd = NL80211_CMD_GET_STATION,
19219: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19220: .doit = nl80211_get_station,
19221: .dumpit = nl80211_dump_station,
19222: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV),
19223: },
19224: {
19225: .cmd = NL80211_CMD_SET_STATION,
19226: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19227: .doit = nl80211_set_station,
19228: .flags = GENL_UNS_ADMIN_PERM,
19229: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19230: },
19231: {
19232: .cmd = NL80211_CMD_NEW_STATION,
19233: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19234: .doit = nl80211_new_station,
19235: .flags = GENL_UNS_ADMIN_PERM,
19236: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19237: },
19238: {
19239: .cmd = NL80211_CMD_DEL_STATION,
19240: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19241: .doit = nl80211_del_station,
19242: .flags = GENL_UNS_ADMIN_PERM,
19243: /* cannot use NL80211_FLAG_MLO_VALID_LINK_ID, depends on
19244: * whether MAC address is passed or not. If MAC address is
19245: * passed, then even during MLO, link ID is not required.
19246: */
19247: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19248: },
19249: {
19250: .cmd = NL80211_CMD_GET_MPATH,
19251: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19252: .doit = nl80211_get_mpath,
19253: .dumpit = nl80211_dump_mpath,
19254: .flags = GENL_UNS_ADMIN_PERM,
19255: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19256: },
19257: {
19258: .cmd = NL80211_CMD_GET_MPP,
19259: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19260: .doit = nl80211_get_mpp,
19261: .dumpit = nl80211_dump_mpp,
19262: .flags = GENL_UNS_ADMIN_PERM,
19263: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19264: },
19265: {
19266: .cmd = NL80211_CMD_SET_MPATH,
19267: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19268: .doit = nl80211_set_mpath,
19269: .flags = GENL_UNS_ADMIN_PERM,
19270: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19271: },
19272: {
19273: .cmd = NL80211_CMD_NEW_MPATH,
19274: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19275: .doit = nl80211_new_mpath,
19276: .flags = GENL_UNS_ADMIN_PERM,
19277: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19278: },
19279: {
19280: .cmd = NL80211_CMD_DEL_MPATH,
19281: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19282: .doit = nl80211_del_mpath,
19283: .flags = GENL_UNS_ADMIN_PERM,
19284: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19285: },
19286: {
19287: .cmd = NL80211_CMD_SET_BSS,
19288: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19289: .doit = nl80211_set_bss,
19290: .flags = GENL_UNS_ADMIN_PERM,
19291: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19292: NL80211_FLAG_MLO_VALID_LINK_ID),
19293: },
19294: {
19295: .cmd = NL80211_CMD_GET_REG,
19296: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19297: .doit = nl80211_get_reg_do,
19298: .dumpit = nl80211_get_reg_dump,
19299: /* can be retrieved by unprivileged users */
19300: },
19301: #ifdef CONFIG_CFG80211_CRDA_SUPPORT
19302: {
19303: .cmd = NL80211_CMD_SET_REG,
19304: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19305: .doit = nl80211_set_reg,
19306: .flags = GENL_ADMIN_PERM,
19307: },
19308: #endif
19309: {
19310: .cmd = NL80211_CMD_REQ_SET_REG,
19311: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19312: .doit = nl80211_req_set_reg,
19313: .flags = GENL_ADMIN_PERM,
19314: },
19315: {
19316: .cmd = NL80211_CMD_RELOAD_REGDB,
19317: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19318: .doit = nl80211_reload_regdb,
19319: .flags = GENL_ADMIN_PERM,
19320: },
19321: {
19322: .cmd = NL80211_CMD_GET_MESH_CONFIG,
19323: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19324: .doit = nl80211_get_mesh_config,
19325: /* can be retrieved by unprivileged users */
19326: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19327: },
19328: {
19329: .cmd = NL80211_CMD_SET_MESH_CONFIG,
19330: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19331: .doit = nl80211_update_mesh_config,
19332: .flags = GENL_UNS_ADMIN_PERM,
19333: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19334: },
19335: {
19336: .cmd = NL80211_CMD_TRIGGER_SCAN,
19337: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19338: .doit = nl80211_trigger_scan,
19339: .flags = GENL_UNS_ADMIN_PERM,
19340: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19341: },
19342: {
19343: .cmd = NL80211_CMD_ABORT_SCAN,
19344: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19345: .doit = nl80211_abort_scan,
19346: .flags = GENL_UNS_ADMIN_PERM,
19347: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19348: },
19349: {
19350: .cmd = NL80211_CMD_GET_SCAN,
19351: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19352: .dumpit = nl80211_dump_scan,
19353: },
19354: {
19355: .cmd = NL80211_CMD_START_SCHED_SCAN,
19356: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19357: .doit = nl80211_start_sched_scan,
19358: .flags = GENL_UNS_ADMIN_PERM,
19359: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19360: },
19361: {
19362: .cmd = NL80211_CMD_STOP_SCHED_SCAN,
19363: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19364: .doit = nl80211_stop_sched_scan,
19365: .flags = GENL_UNS_ADMIN_PERM,
19366: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19367: },
19368: {
19369: .cmd = NL80211_CMD_AUTHENTICATE,
19370: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19371: .doit = nl80211_authenticate,
19372: .flags = GENL_UNS_ADMIN_PERM,
19373: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19374: NL80211_FLAG_CLEAR_SKB),
19375: },
19376: {
19377: .cmd = NL80211_CMD_ASSOCIATE,
19378: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19379: .doit = nl80211_associate,
19380: .flags = GENL_UNS_ADMIN_PERM,
19381: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19382: NL80211_FLAG_CLEAR_SKB),
19383: },
19384: {
19385: .cmd = NL80211_CMD_DEAUTHENTICATE,
19386: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19387: .doit = nl80211_deauthenticate,
19388: .flags = GENL_UNS_ADMIN_PERM,
19389: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19390: },
19391: {
19392: .cmd = NL80211_CMD_DISASSOCIATE,
19393: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19394: .doit = nl80211_disassociate,
19395: .flags = GENL_UNS_ADMIN_PERM,
19396: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19397: },
19398: {
19399: .cmd = NL80211_CMD_JOIN_IBSS,
19400: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19401: .doit = nl80211_join_ibss,
19402: .flags = GENL_UNS_ADMIN_PERM,
19403: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19404: },
19405: {
19406: .cmd = NL80211_CMD_LEAVE_IBSS,
19407: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19408: .doit = nl80211_leave_ibss,
19409: .flags = GENL_UNS_ADMIN_PERM,
19410: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19411: },
19412: #ifdef CONFIG_NL80211_TESTMODE
19413: {
19414: .cmd = NL80211_CMD_TESTMODE,
19415: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19416: .doit = nl80211_testmode_do,
19417: .dumpit = nl80211_testmode_dump,
19418: .flags = GENL_UNS_ADMIN_PERM,
19419: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
19420: },
19421: #endif
19422: {
19423: .cmd = NL80211_CMD_CONNECT,
19424: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19425: .doit = nl80211_connect,
19426: .flags = GENL_UNS_ADMIN_PERM,
19427: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19428: NL80211_FLAG_CLEAR_SKB),
19429: },
19430: {
19431: .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
19432: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19433: .doit = nl80211_update_connect_params,
19434: .flags = GENL_ADMIN_PERM,
19435: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19436: NL80211_FLAG_CLEAR_SKB),
19437: },
19438: {
19439: .cmd = NL80211_CMD_DISCONNECT,
19440: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19441: .doit = nl80211_disconnect,
19442: .flags = GENL_UNS_ADMIN_PERM,
19443: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19444: },
19445: {
19446: .cmd = NL80211_CMD_SET_WIPHY_NETNS,
19447: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19448: .doit = nl80211_wiphy_netns,
19449: .flags = GENL_UNS_ADMIN_PERM,
19450: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY |
19451: NL80211_FLAG_NEED_RTNL |
19452: NL80211_FLAG_NO_WIPHY_MTX),
19453: },
19454: {
19455: .cmd = NL80211_CMD_GET_SURVEY,
19456: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19457: .dumpit = nl80211_dump_survey,
19458: },
19459: {
19460: .cmd = NL80211_CMD_SET_PMKSA,
19461: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19462: .doit = nl80211_set_pmksa,
19463: .flags = GENL_UNS_ADMIN_PERM,
19464: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19465: NL80211_FLAG_CLEAR_SKB),
19466: },
19467: {
19468: .cmd = NL80211_CMD_DEL_PMKSA,
19469: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19470: .doit = nl80211_del_pmksa,
19471: .flags = GENL_UNS_ADMIN_PERM,
19472: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19473: },
19474: {
19475: .cmd = NL80211_CMD_FLUSH_PMKSA,
19476: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19477: .doit = nl80211_flush_pmksa,
19478: .flags = GENL_UNS_ADMIN_PERM,
19479: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19480: },
19481: {
19482: .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
19483: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19484: .doit = nl80211_remain_on_channel,
19485: .flags = GENL_UNS_ADMIN_PERM,
19486: /* FIXME: requiring a link ID here is probably not good */
19487: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
19488: NL80211_FLAG_MLO_VALID_LINK_ID),
19489: },
19490: {
19491: .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
19492: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19493: .doit = nl80211_cancel_remain_on_channel,
19494: .flags = GENL_UNS_ADMIN_PERM,
19495: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19496: },
19497: {
19498: .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
19499: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19500: .doit = nl80211_set_tx_bitrate_mask,
19501: .flags = GENL_UNS_ADMIN_PERM,
19502: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
19503: NL80211_FLAG_MLO_VALID_LINK_ID),
19504: },
19505: {
19506: .cmd = NL80211_CMD_REGISTER_FRAME,
19507: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19508: .doit = nl80211_register_mgmt,
19509: .flags = GENL_UNS_ADMIN_PERM,
19510: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV),
19511: },
19512: {
19513: .cmd = NL80211_CMD_FRAME,
19514: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19515: .doit = nl80211_tx_mgmt,
19516: .flags = GENL_UNS_ADMIN_PERM,
19517: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19518: },
19519: {
19520: .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
19521: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19522: .doit = nl80211_tx_mgmt_cancel_wait,
19523: .flags = GENL_UNS_ADMIN_PERM,
19524: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19525: },
19526: {
19527: .cmd = NL80211_CMD_SET_POWER_SAVE,
19528: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19529: .doit = nl80211_set_power_save,
19530: .flags = GENL_UNS_ADMIN_PERM,
19531: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
19532: },
19533: {
19534: .cmd = NL80211_CMD_GET_POWER_SAVE,
19535: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19536: .doit = nl80211_get_power_save,
19537: /* can be retrieved by unprivileged users */
19538: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
19539: },
19540: {
19541: .cmd = NL80211_CMD_SET_CQM,
19542: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19543: .doit = nl80211_set_cqm,
19544: .flags = GENL_UNS_ADMIN_PERM,
19545: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
19546: },
19547: {
19548: .cmd = NL80211_CMD_SET_CHANNEL,
19549: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19550: .doit = nl80211_set_channel,
19551: .flags = GENL_UNS_ADMIN_PERM,
19552: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
19553: NL80211_FLAG_MLO_VALID_LINK_ID),
19554: },
19555: {
19556: .cmd = NL80211_CMD_JOIN_MESH,
19557: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19558: .doit = nl80211_join_mesh,
19559: .flags = GENL_UNS_ADMIN_PERM,
19560: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19561: },
19562: {
19563: .cmd = NL80211_CMD_LEAVE_MESH,
19564: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19565: .doit = nl80211_leave_mesh,
19566: .flags = GENL_UNS_ADMIN_PERM,
19567: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19568: },
19569: {
19570: .cmd = NL80211_CMD_JOIN_OCB,
19571: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19572: .doit = nl80211_join_ocb,
19573: .flags = GENL_UNS_ADMIN_PERM,
19574: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19575: },
19576: {
19577: .cmd = NL80211_CMD_LEAVE_OCB,
19578: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19579: .doit = nl80211_leave_ocb,
19580: .flags = GENL_UNS_ADMIN_PERM,
19581: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19582: },
19583: #ifdef CONFIG_PM
19584: {
19585: .cmd = NL80211_CMD_GET_WOWLAN,
19586: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19587: .doit = nl80211_get_wowlan,
19588: /* can be retrieved by unprivileged users */
19589: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
19590: },
19591: {
19592: .cmd = NL80211_CMD_SET_WOWLAN,
19593: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19594: .doit = nl80211_set_wowlan,
19595: .flags = GENL_UNS_ADMIN_PERM,
19596: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
19597: },
19598: #endif
19599: {
19600: .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
19601: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19602: .doit = nl80211_set_rekey_data,
19603: .flags = GENL_UNS_ADMIN_PERM,
19604: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19605: NL80211_FLAG_CLEAR_SKB),
19606: },
19607: {
19608: .cmd = NL80211_CMD_TDLS_MGMT,
19609: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19610: .doit = nl80211_tdls_mgmt,
19611: .flags = GENL_UNS_ADMIN_PERM,
19612: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19613: NL80211_FLAG_MLO_VALID_LINK_ID),
19614: },
19615: {
19616: .cmd = NL80211_CMD_TDLS_OPER,
19617: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19618: .doit = nl80211_tdls_oper,
19619: .flags = GENL_UNS_ADMIN_PERM,
19620: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19621: },
19622: {
19623: .cmd = NL80211_CMD_UNEXPECTED_FRAME,
19624: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19625: .doit = nl80211_register_unexpected_frame,
19626: .flags = GENL_UNS_ADMIN_PERM,
19627: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
19628: },
19629: {
19630: .cmd = NL80211_CMD_PROBE_CLIENT,
19631: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19632: .doit = nl80211_probe_client,
19633: .flags = GENL_UNS_ADMIN_PERM,
19634: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19635: },
19636: {
19637: .cmd = NL80211_CMD_REGISTER_BEACONS,
19638: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19639: .doit = nl80211_register_beacons,
19640: .flags = GENL_UNS_ADMIN_PERM,
19641: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
19642: },
19643: {
19644: .cmd = NL80211_CMD_SET_NOACK_MAP,
19645: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19646: .doit = nl80211_set_noack_map,
19647: .flags = GENL_UNS_ADMIN_PERM,
19648: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
19649: },
19650: {
19651: .cmd = NL80211_CMD_START_P2P_DEVICE,
19652: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19653: .doit = nl80211_start_p2p_device,
19654: .flags = GENL_UNS_ADMIN_PERM,
19655: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV |
19656: NL80211_FLAG_NEED_RTNL),
19657: },
19658: {
19659: .cmd = NL80211_CMD_STOP_P2P_DEVICE,
19660: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19661: .doit = nl80211_stop_p2p_device,
19662: .flags = GENL_UNS_ADMIN_PERM,
19663: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
19664: NL80211_FLAG_NEED_RTNL),
19665: },
19666: {
19667: .cmd = NL80211_CMD_START_NAN,
19668: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19669: .doit = nl80211_start_nan,
19670: .flags = GENL_ADMIN_PERM,
19671: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV |
19672: NL80211_FLAG_NEED_RTNL),
19673: },
19674: {
19675: .cmd = NL80211_CMD_STOP_NAN,
19676: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19677: .doit = nl80211_stop_nan,
19678: .flags = GENL_ADMIN_PERM,
19679: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
19680: NL80211_FLAG_NO_WIPHY_MTX |
19681: NL80211_FLAG_NEED_RTNL),
19682: },
19683: {
19684: .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
19685: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19686: .doit = nl80211_nan_add_func,
19687: .flags = GENL_ADMIN_PERM,
19688: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19689: },
19690: {
19691: .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
19692: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19693: .doit = nl80211_nan_del_func,
19694: .flags = GENL_ADMIN_PERM,
19695: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19696: },
19697: {
19698: .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
19699: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19700: .doit = nl80211_nan_change_config,
19701: .flags = GENL_ADMIN_PERM,
19702: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19703: },
19704: {
19705: .cmd = NL80211_CMD_SET_MCAST_RATE,
19706: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19707: .doit = nl80211_set_mcast_rate,
19708: .flags = GENL_UNS_ADMIN_PERM,
19709: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
19710: },
19711: {
19712: .cmd = NL80211_CMD_SET_MAC_ACL,
19713: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19714: .doit = nl80211_set_mac_acl,
19715: .flags = GENL_UNS_ADMIN_PERM,
19716: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
19717: NL80211_FLAG_MLO_UNSUPPORTED),
19718: },
19719: {
19720: .cmd = NL80211_CMD_RADAR_DETECT,
19721: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19722: .doit = nl80211_start_radar_detection,
19723: .flags = GENL_UNS_ADMIN_PERM,
19724: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19725: NL80211_FLAG_NO_WIPHY_MTX |
19726: NL80211_FLAG_MLO_VALID_LINK_ID),
19727: },
19728: {
19729: .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
19730: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19731: .doit = nl80211_get_protocol_features,
19732: },
19733: {
19734: .cmd = NL80211_CMD_UPDATE_FT_IES,
19735: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19736: .doit = nl80211_update_ft_ies,
19737: .flags = GENL_UNS_ADMIN_PERM,
19738: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19739: },
19740: {
19741: .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
19742: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19743: .doit = nl80211_crit_protocol_start,
19744: .flags = GENL_UNS_ADMIN_PERM,
19745: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19746: },
19747: {
19748: .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
19749: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19750: .doit = nl80211_crit_protocol_stop,
19751: .flags = GENL_UNS_ADMIN_PERM,
19752: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19753: },
19754: {
19755: .cmd = NL80211_CMD_GET_COALESCE,
19756: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19757: .doit = nl80211_get_coalesce,
19758: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
19759: },
19760: {
19761: .cmd = NL80211_CMD_SET_COALESCE,
19762: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19763: .doit = nl80211_set_coalesce,
19764: .flags = GENL_UNS_ADMIN_PERM,
19765: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
19766: },
19767: {
19768: .cmd = NL80211_CMD_CHANNEL_SWITCH,
19769: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19770: .doit = nl80211_channel_switch,
19771: .flags = GENL_UNS_ADMIN_PERM,
19772: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19773: NL80211_FLAG_MLO_VALID_LINK_ID),
19774: },
19775: {
19776: .cmd = NL80211_CMD_VENDOR,
19777: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19778: .doit = nl80211_vendor_cmd,
19779: .dumpit = nl80211_vendor_cmd_dump,
19780: .flags = GENL_UNS_ADMIN_PERM,
19781: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY |
19782: NL80211_FLAG_CLEAR_SKB),
19783: },
19784: {
19785: .cmd = NL80211_CMD_SET_QOS_MAP,
19786: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19787: .doit = nl80211_set_qos_map,
19788: .flags = GENL_UNS_ADMIN_PERM,
19789: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19790: },
19791: {
19792: .cmd = NL80211_CMD_ADD_TX_TS,
19793: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19794: .doit = nl80211_add_tx_ts,
19795: .flags = GENL_UNS_ADMIN_PERM,
19796: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19797: NL80211_FLAG_MLO_UNSUPPORTED),
19798: },
19799: {
19800: .cmd = NL80211_CMD_DEL_TX_TS,
19801: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19802: .doit = nl80211_del_tx_ts,
19803: .flags = GENL_UNS_ADMIN_PERM,
19804: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19805: },
19806: {
19807: .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
19808: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19809: .doit = nl80211_tdls_channel_switch,
19810: .flags = GENL_UNS_ADMIN_PERM,
19811: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19812: },
19813: {
19814: .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
19815: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19816: .doit = nl80211_tdls_cancel_channel_switch,
19817: .flags = GENL_UNS_ADMIN_PERM,
19818: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19819: },
19820: {
19821: .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
19822: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19823: .doit = nl80211_set_multicast_to_unicast,
19824: .flags = GENL_UNS_ADMIN_PERM,
19825: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
19826: },
19827: {
19828: .cmd = NL80211_CMD_SET_PMK,
19829: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19830: .doit = nl80211_set_pmk,
19831: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19832: NL80211_FLAG_CLEAR_SKB),
19833: },
19834: {
19835: .cmd = NL80211_CMD_DEL_PMK,
19836: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19837: .doit = nl80211_del_pmk,
19838: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19839: },
19840: {
19841: .cmd = NL80211_CMD_EXTERNAL_AUTH,
19842: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19843: .doit = nl80211_external_auth,
19844: .flags = GENL_ADMIN_PERM,
19845: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19846: },
19847: {
19848: .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
19849: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19850: .doit = nl80211_tx_control_port,
19851: .flags = GENL_UNS_ADMIN_PERM,
19852: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19853: },
19854: {
19855: .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
19856: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19857: .doit = nl80211_get_ftm_responder_stats,
19858: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
19859: NL80211_FLAG_MLO_VALID_LINK_ID),
19860: },
19861: {
19862: .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
19863: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19864: .doit = nl80211_pmsr_start,
19865: .flags = GENL_UNS_ADMIN_PERM,
19866: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19867: },
19868: {
19869: .cmd = NL80211_CMD_NOTIFY_RADAR,
19870: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19871: .doit = nl80211_notify_radar_detection,
19872: .flags = GENL_UNS_ADMIN_PERM,
19873: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19874: },
19875: {
19876: .cmd = NL80211_CMD_UPDATE_OWE_INFO,
19877: .doit = nl80211_update_owe_info,
19878: .flags = GENL_ADMIN_PERM,
19879: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19880: },
19881: {
19882: .cmd = NL80211_CMD_PROBE_MESH_LINK,
19883: .doit = nl80211_probe_mesh_link,
19884: .flags = GENL_UNS_ADMIN_PERM,
19885: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19886: },
19887: {
19888: .cmd = NL80211_CMD_SET_TID_CONFIG,
19889: .doit = nl80211_set_tid_config,
19890: .flags = GENL_UNS_ADMIN_PERM,
19891: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
19892: NL80211_FLAG_MLO_VALID_LINK_ID),
19893: },
19894: {
19895: .cmd = NL80211_CMD_SET_SAR_SPECS,
19896: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19897: .doit = nl80211_set_sar_specs,
19898: .flags = GENL_UNS_ADMIN_PERM,
19899: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY |
19900: NL80211_FLAG_NEED_RTNL),
19901: },
19902: {
19903: .cmd = NL80211_CMD_COLOR_CHANGE_REQUEST,
19904: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19905: .doit = nl80211_color_change,
19906: .flags = GENL_UNS_ADMIN_PERM,
19907: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19908: NL80211_FLAG_MLO_VALID_LINK_ID),
19909: },
19910: {
19911: .cmd = NL80211_CMD_SET_FILS_AAD,
19912: .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19913: .doit = nl80211_set_fils_aad,
19914: .flags = GENL_UNS_ADMIN_PERM,
19915: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19916: },
19917: {
19918: .cmd = NL80211_CMD_ADD_LINK,
19919: .doit = nl80211_add_link,
19920: .flags = GENL_UNS_ADMIN_PERM,
19921: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19922: },
19923: {
19924: .cmd = NL80211_CMD_REMOVE_LINK,
19925: .doit = nl80211_remove_link,
19926: .flags = GENL_UNS_ADMIN_PERM,
19927: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19928: NL80211_FLAG_MLO_VALID_LINK_ID),
19929: },
19930: {
19931: .cmd = NL80211_CMD_ADD_LINK_STA,
19932: .doit = nl80211_add_link_station,
19933: .flags = GENL_UNS_ADMIN_PERM,
19934: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19935: NL80211_FLAG_MLO_VALID_LINK_ID),
19936: },
19937: {
19938: .cmd = NL80211_CMD_MODIFY_LINK_STA,
19939: .doit = nl80211_modify_link_station,
19940: .flags = GENL_UNS_ADMIN_PERM,
19941: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19942: NL80211_FLAG_MLO_VALID_LINK_ID),
19943: },
19944: {
19945: .cmd = NL80211_CMD_REMOVE_LINK_STA,
19946: .doit = nl80211_remove_link_station,
19947: .flags = GENL_UNS_ADMIN_PERM,
19948: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
19949: NL80211_FLAG_MLO_VALID_LINK_ID),
19950: },
19951: {
19952: .cmd = NL80211_CMD_SET_HW_TIMESTAMP,
19953: .doit = nl80211_set_hw_timestamp,
19954: .flags = GENL_UNS_ADMIN_PERM,
19955: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19956: },
19957: {
19958: .cmd = NL80211_CMD_SET_TID_TO_LINK_MAPPING,
19959: .doit = nl80211_set_ttlm,
19960: .flags = GENL_UNS_ADMIN_PERM,
19961: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19962: },
19963: {
19964: .cmd = NL80211_CMD_ASSOC_MLO_RECONF,
19965: .doit = nl80211_assoc_ml_reconf,
19966: .flags = GENL_UNS_ADMIN_PERM,
19967: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19968: },
19969: {
19970: .cmd = NL80211_CMD_EPCS_CFG,
19971: .doit = nl80211_epcs_cfg,
19972: .flags = GENL_UNS_ADMIN_PERM,
19973: .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
19974: },
19975: {
19976: .cmd = NL80211_CMD_NAN_SET_LOCAL_SCHED,
19977: .doit = nl80211_nan_set_local_sched,
19978: .flags = GENL_ADMIN_PERM,
19979: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19980: },
19981: {
19982: .cmd = NL80211_CMD_NAN_SET_PEER_SCHED,
19983: .doit = nl80211_nan_set_peer_sched,
19984: .flags = GENL_ADMIN_PERM,
19985: .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
19986: },
19987: };
SourceFile:net/wireless/nl80211.c]
|
| 26/2 |
2026/05/17 19:06 |
llm |
expert |
0m
Model:
Tokens:
input: 66979
output: 29
thoughts: 756
Thoughts: **Analyzing the Potential Exploit**
Okay, so I'm looking at this potential bug and my initial thought is: the commands `NL80211_CMD_SET_INTERFACE` and `NL80211_CMD_JOIN_OCB`, which are the entry points here, require `CAP_NET_ADMIN` in the user namespace because of the `GENL_UNS_ADMIN_PERM` flag. Since the scenario explicitly denies user namespaces, a directly unprivileged process is out of the question as an initial attack vector. Good.
I've got the kernel source up. Now let's dive into this `WARN` in `mac80211_hwsim_sta_rc_update`. The report mentions the bug is a `WARN`. In a production kernel build, this is a non-fatal warning, so it won't crash the kernel on its own. It's just a sanity check. Now, my immediate question: is this `WARN` *precursor* to something else, like a memory corruption? I have to trace what happens after the warning.
Looking at the code after the `WARN`, it looks like the loop continues. I see no obvious memory corruption based on the `WARN` condition alone.
Now, I'm going to look at how `bw` is used. I see `bw` is initialized to `U32_MAX`. Then, it's assigned a value within a `switch` statement based on `link_sta->bandwidth`. If `link_sta->bandwidth` is anything *other* than 20, 40, 80, 160, or 320, then the original value of `U32_MAX` is retained. Thus `bw > hwsim_get_chanwidth(confbw)` will evaluate to TRUE, and we'll get the warning.
Wait, the report states the bad STA has a bandwidth of 20 MHz, but the value is `(0)`. That means `link_sta->bandwidth` is `0`. The report also states `channel config 10 MHz (7)`. Let's confirm that `IEEE80211_STA_RX_BW_20` is a valid constant within the possible values of `link_sta->bandwidth`.
|
| 27/2 |
2026/05/17 19:06 |
tool |
grepper |
0m
Args: map[Expression:IEEE80211_STA_RX_BW_20]
Results: map[Output:drivers/net/wireless/ath/ath10k/mac.c=2723=static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar,
--
drivers/net/wireless/ath/ath10k/mac.c-2745-
drivers/net/wireless/ath/ath10k/mac.c:2746: if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/ath/ath10k/mac.c-2747- return MODE_11AC_VHT20;
--
drivers/net/wireless/ath/ath10k/mac.c=8557=static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
--
drivers/net/wireless/ath/ath10k/mac.c-8588- switch (sta->deflink.bandwidth) {
drivers/net/wireless/ath/ath10k/mac.c:8589: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/ath/ath10k/mac.c-8590- bw = WMI_PEER_CHWIDTH_20MHZ;
--
drivers/net/wireless/ath/ath11k/mac.c=2789=static enum wmi_phy_mode ath11k_mac_get_phymode_vht(struct ath11k *ar,
--
drivers/net/wireless/ath/ath11k/mac.c-2810-
drivers/net/wireless/ath/ath11k/mac.c:2811: if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/ath/ath11k/mac.c-2812- return MODE_11AC_VHT20;
--
drivers/net/wireless/ath/ath11k/mac.c=2817=static enum wmi_phy_mode ath11k_mac_get_phymode_he(struct ath11k *ar,
--
drivers/net/wireless/ath/ath11k/mac.c-2836-
drivers/net/wireless/ath/ath11k/mac.c:2837: if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/ath/ath11k/mac.c-2838- return MODE_11AX_HE20;
--
drivers/net/wireless/ath/ath11k/mac.c=5244=static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar,
--
drivers/net/wireless/ath/ath11k/mac.c-5249- switch (sta->deflink.bandwidth) {
drivers/net/wireless/ath/ath11k/mac.c:5250: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/ath/ath11k/mac.c-5251- bw = WMI_PEER_CHWIDTH_20MHZ;
--
drivers/net/wireless/ath/ath12k/mac.c=3059=static enum wmi_phy_mode ath12k_mac_get_phymode_vht(struct ath12k *ar,
--
drivers/net/wireless/ath/ath12k/mac.c-3078-
drivers/net/wireless/ath/ath12k/mac.c:3079: if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/ath/ath12k/mac.c-3080- return MODE_11AC_VHT20;
--
drivers/net/wireless/ath/ath12k/mac.c=3085=static enum wmi_phy_mode ath12k_mac_get_phymode_he(struct ath12k *ar,
--
drivers/net/wireless/ath/ath12k/mac.c-3101-
drivers/net/wireless/ath/ath12k/mac.c:3102: if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/ath/ath12k/mac.c-3103- return MODE_11AX_HE20;
--
drivers/net/wireless/ath/ath12k/mac.c=3108=static enum wmi_phy_mode ath12k_mac_get_phymode_eht(struct ath12k *ar,
--
drivers/net/wireless/ath/ath12k/mac.c-3132-
drivers/net/wireless/ath/ath12k/mac.c:3133: if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/ath/ath12k/mac.c-3134- return MODE_11BE_EHT20;
--
drivers/net/wireless/ath/ath12k/mac.c=3796=static u32 ath12k_mac_ieee80211_sta_bw_to_wmi(struct ath12k *ar,
--
drivers/net/wireless/ath/ath12k/mac.c-3801- switch (link_sta->bandwidth) {
drivers/net/wireless/ath/ath12k/mac.c:3802: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/ath/ath12k/mac.c-3803- bw = WMI_PEER_CHWIDTH_20MHZ;
--
drivers/net/wireless/intel/iwlwifi/mld/tlc.c=18=static u8 iwl_mld_fw_bw_from_sta_bw(const struct ieee80211_link_sta *link_sta)
--
drivers/net/wireless/intel/iwlwifi/mld/tlc.c-28- return IWL_TLC_MNG_CH_WIDTH_40MHZ;
drivers/net/wireless/intel/iwlwifi/mld/tlc.c:29: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/intel/iwlwifi/mld/tlc.c-30- default:
--
drivers/net/wireless/intel/iwlwifi/mld/tlc.c=167=iwl_mld_fill_vht_rates(const struct ieee80211_link_sta *link_sta,
--
drivers/net/wireless/intel/iwlwifi/mld/tlc.c-190- supp = BIT(highest_mcs + 1) - 1;
drivers/net/wireless/intel/iwlwifi/mld/tlc.c:191: if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/intel/iwlwifi/mld/tlc.c-192- supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9);
--
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c=12=static u8 rs_fw_bw_from_sta_bw(const struct ieee80211_link_sta *link_sta)
--
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c-22- return IWL_TLC_MNG_CH_WIDTH_40MHZ;
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c:23: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c-24- default:
--
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c=136=rs_fw_vht_set_enabled_rates(const struct ieee80211_link_sta *link_sta,
--
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c-159- supp = BIT(highest_mcs + 1) - 1;
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c:160: if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c-161- supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9);
--
drivers/net/wireless/intel/iwlwifi/mvm/rs.c=1372=static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
--
drivers/net/wireless/intel/iwlwifi/mvm/rs.c-1399- return RATE_MCS_CHAN_WIDTH_40;
drivers/net/wireless/intel/iwlwifi/mvm/rs.c:1400: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/intel/iwlwifi/mvm/rs.c-1401- default:
--
drivers/net/wireless/intel/iwlwifi/mvm/rs.c=2764=static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
--
drivers/net/wireless/intel/iwlwifi/mvm/rs.c-2777- if (i == IWL_RATE_MCS_9_INDEX &&
drivers/net/wireless/intel/iwlwifi/mvm/rs.c:2778: sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/intel/iwlwifi/mvm/rs.c-2779- continue;
--
drivers/net/wireless/intel/iwlwifi/mvm/rs.c-2795- if (i == IWL_RATE_MCS_9_INDEX &&
drivers/net/wireless/intel/iwlwifi/mvm/rs.c:2796: sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/intel/iwlwifi/mvm/rs.c-2797- continue;
--
drivers/net/wireless/intel/iwlwifi/mvm/sta.c=128=int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
--
drivers/net/wireless/intel/iwlwifi/mvm/sta.c-172- fallthrough;
drivers/net/wireless/intel/iwlwifi/mvm/sta.c:173: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/intel/iwlwifi/mvm/sta.c-174- if (sta->deflink.ht_cap.ht_supported)
--
drivers/net/wireless/mediatek/mt76/mt76_connac.h=51=enum {
drivers/net/wireless/mediatek/mt76/mt76_connac.h:52: CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20,
drivers/net/wireless/mediatek/mt76/mt76_connac.h-53- CMD_CBW_40MHZ = IEEE80211_STA_RX_BW_40,
--
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c=1030=int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
--
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c-1104- switch (bw) {
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c:1105: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c-1106- break;
--
drivers/net/wireless/mediatek/mt76/mt7915/mac.c=90=static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
--
drivers/net/wireless/mediatek/mt76/mt7915/mac.c-200- default:
drivers/net/wireless/mediatek/mt76/mt7915/mac.c:201: bw = IEEE80211_STA_RX_BW_20;
drivers/net/wireless/mediatek/mt76/mt7915/mac.c-202- break;
--
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c=1240=mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
--
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c-1301- break;
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c:1302: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c-1303- default:
--
drivers/net/wireless/mediatek/mt76/mt7921/mac.c=32=static void mt7921_mac_sta_poll(struct mt792x_dev *dev)
--
drivers/net/wireless/mediatek/mt76/mt7921/mac.c-134- default:
drivers/net/wireless/mediatek/mt76/mt7921/mac.c:135: bw = IEEE80211_STA_RX_BW_20;
drivers/net/wireless/mediatek/mt76/mt7921/mac.c-136- break;
--
drivers/net/wireless/mediatek/mt76/mt7925/mac.c=22=static void mt7925_mac_sta_poll(struct mt792x_dev *dev)
--
drivers/net/wireless/mediatek/mt76/mt7925/mac.c-118- default:
drivers/net/wireless/mediatek/mt76/mt7925/mac.c:119: bw = IEEE80211_STA_RX_BW_20;
drivers/net/wireless/mediatek/mt76/mt7925/mac.c-120- break;
--
drivers/net/wireless/mediatek/mt76/mt7925/mac.c=249=mt7925_mac_fill_rx_rate(struct mt792x_dev *dev,
--
drivers/net/wireless/mediatek/mt76/mt7925/mac.c-323- switch (bw) {
drivers/net/wireless/mediatek/mt76/mt7925/mac.c:324: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/mediatek/mt76/mt7925/mac.c-325- break;
--
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c=1645=mt7925_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_link_sta *link_sta)
--
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c-1665-
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c:1666: if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c-1667- memcpy(eht->mcs_map_bw20, &mcs_map->only_20mhz, sizeof(eht->mcs_map_bw20));
--
drivers/net/wireless/mediatek/mt76/mt7996/mac.c=274=mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
--
drivers/net/wireless/mediatek/mt76/mt7996/mac.c-348- switch (bw) {
drivers/net/wireless/mediatek/mt76/mt7996/mac.c:349: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/mediatek/mt76/mt7996/mac.c-350- break;
--
drivers/net/wireless/realtek/rtlwifi/rc.c=15=static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
--
drivers/net/wireless/realtek/rtlwifi/rc.c-68- } else if (wireless_mode == WIRELESS_MODE_AC_24G) {
drivers/net/wireless/realtek/rtlwifi/rc.c:69: if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) {
drivers/net/wireless/realtek/rtlwifi/rc.c-70- ieee80211_rate_set_vht(&rate,
--
drivers/net/wireless/realtek/rtlwifi/rc.c-90- } else if (wireless_mode == WIRELESS_MODE_AC_5G) {
drivers/net/wireless/realtek/rtlwifi/rc.c:91: if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) {
drivers/net/wireless/realtek/rtlwifi/rc.c-92- ieee80211_rate_set_vht(&rate,
--
drivers/net/wireless/realtek/rtw89/phy.c=122=static u64 get_eht_ra_mask(struct rtw89_vif_link *rtwvif_link,
--
drivers/net/wireless/realtek/rtw89/phy.c-139- return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
drivers/net/wireless/realtek/rtw89/phy.c:140: case IEEE80211_STA_RX_BW_20:
drivers/net/wireless/realtek/rtw89/phy.c-141- if (vif->type == NL80211_IFTYPE_AP &&
--
drivers/net/wireless/realtek/rtw89/phy.c=322=static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
--
drivers/net/wireless/realtek/rtw89/phy.c-377- /* MCS9 (non-20MHz), MCS8, MCS7 */
drivers/net/wireless/realtek/rtw89/phy.c:378: if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
drivers/net/wireless/realtek/rtw89/phy.c-379- ra_mask |= get_mcs_ra_mask(mcs_map, 8, 1);
--
include/net/mac80211.h=2468=enum ieee80211_sta_state {
--
include/net/mac80211.h-2478- * enum ieee80211_sta_rx_bandwidth - station RX bandwidth
include/net/mac80211.h:2479: * @IEEE80211_STA_RX_BW_20: station can only receive 20 MHz
include/net/mac80211.h-2480- * @IEEE80211_STA_RX_BW_40: station can receive up to 40 MHz
--
include/net/mac80211.h=2489=enum ieee80211_sta_rx_bandwidth {
include/net/mac80211.h:2490: IEEE80211_STA_RX_BW_20 = 0,
include/net/mac80211.h-2491- IEEE80211_STA_RX_BW_40,
--
include/net/mac80211.h=8044=ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
--
include/net/mac80211.h-8051- case NL80211_CHAN_WIDTH_20:
include/net/mac80211.h:8052: return IEEE80211_STA_RX_BW_20;
include/net/mac80211.h-8053- case NL80211_CHAN_WIDTH_40:
--
net/mac80211/chan.c=441=static enum nl80211_chan_width ieee80211_get_sta_bw(struct sta_info *sta,
--
net/mac80211/chan.c-462- switch (width) {
net/mac80211/chan.c:463: case IEEE80211_STA_RX_BW_20:
net/mac80211/chan.c-464- if (link_sta->pub->ht_cap.ht_supported)
--
net/mac80211/ht.c=138=bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
--
net/mac80211/ht.c-278- case NL80211_CHAN_WIDTH_20:
net/mac80211/ht.c:279: bw = IEEE80211_STA_RX_BW_20;
net/mac80211/ht.c-280- break;
--
net/mac80211/ht.c-286- bw = ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
net/mac80211/ht.c:287: IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20;
net/mac80211/ht.c-288- break;
--
net/mac80211/ht.c-295- ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
net/mac80211/ht.c:296: IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20;
net/mac80211/ht.c-297-
--
net/mac80211/ht.c=623=void ieee80211_ht_handle_chanwidth_notif(struct ieee80211_local *local,
--
net/mac80211/ht.c-635- if (chanwidth == IEEE80211_HT_CHANWIDTH_20MHZ)
net/mac80211/ht.c:636: max_bw = IEEE80211_STA_RX_BW_20;
net/mac80211/ht.c-637- else
--
net/mac80211/mesh_plink.c=159=static u64 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
--
net/mac80211/mesh_plink.c-180-
net/mac80211/mesh_plink.c:181: if (sta->sta.deflink.bandwidth > IEEE80211_STA_RX_BW_20)
net/mac80211/mesh_plink.c-182- continue;
--
net/mac80211/mesh_plink.c=425=static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
--
net/mac80211/mesh_plink.c-479- IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
net/mac80211/mesh_plink.c:480: if (sta->sta.deflink.bandwidth != IEEE80211_STA_RX_BW_20)
net/mac80211/mesh_plink.c-481- changed |= IEEE80211_RC_BW_CHANGED;
net/mac80211/mesh_plink.c:482: sta->sta.deflink.bandwidth = IEEE80211_STA_RX_BW_20;
net/mac80211/mesh_plink.c-483- }
--
net/mac80211/sta_info.c=549=static int sta_info_alloc_link(struct ieee80211_local *local,
--
net/mac80211/sta_info.c-579- switch (link_info->cur_max_bandwidth) {
net/mac80211/sta_info.c:580: case IEEE80211_STA_RX_BW_20:
net/mac80211/sta_info.c-581- case IEEE80211_STA_RX_BW_40:
--
net/mac80211/vht.c=362=__ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta,
--
net/mac80211/vht.c-382- sdata->vif.type == NL80211_IFTYPE_NAN))
net/mac80211/vht.c:383: return IEEE80211_STA_RX_BW_20;
net/mac80211/vht.c-384-
--
net/mac80211/vht.c-402- return IEEE80211_STA_RX_BW_40;
net/mac80211/vht.c:403: return IEEE80211_STA_RX_BW_20;
net/mac80211/vht.c-404- }
--
net/mac80211/vht.c-412-
net/mac80211/vht.c:413: return IEEE80211_STA_RX_BW_20;
net/mac80211/vht.c-414- }
--
net/mac80211/vht.c-418- IEEE80211_STA_RX_BW_40 :
net/mac80211/vht.c:419: IEEE80211_STA_RX_BW_20;
net/mac80211/vht.c-420-
--
net/mac80211/vht.c=485=ieee80211_sta_rx_bw_to_chan_width(struct link_sta_info *link_sta)
--
net/mac80211/vht.c-493- switch (cur_bw) {
net/mac80211/vht.c:494: case IEEE80211_STA_RX_BW_20:
net/mac80211/vht.c-495- if (!link_sta->pub->ht_cap.ht_supported)
--
net/mac80211/vht.c=518=_ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta,
--
net/mac80211/vht.c-532- sta->sdata->vif.type == NL80211_IFTYPE_NAN_DATA))
net/mac80211/vht.c:533: return IEEE80211_STA_RX_BW_20;
net/mac80211/vht.c-534-
--
net/mac80211/vht.c-538- rcu_read_unlock();
net/mac80211/vht.c:539: return IEEE80211_STA_RX_BW_20;
net/mac80211/vht.c-540- }
--
net/mac80211/vht.c=664=u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
--
net/mac80211/vht.c-700- /* ignore IEEE80211_OPMODE_NOTIF_BW_160_80P80 must not be set */
net/mac80211/vht.c:701: link_sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20;
net/mac80211/vht.c-702- break;
]
|
| 28/2 |
2026/05/17 19:06 |
llm |
expert |
0m
Model:
Tokens:
input: 76110
output: 55
thoughts: 62
Thoughts: **Analyzing the Wireless Configuration**
Okay, so I'm looking at this wireless configuration and the `IEEE80211_STA_RX_BW_20` flag is currently set to `0`. That means the bandwidth (`bw`) is going to be assigned a value of `20`. Now, the next step is calling `hwsim_get_chanwidth(confbw)`. Let me shift my focus to `hwsim_get_chanwidth` and see what's happening under the hood there; that's where the channel width determination is taking place. I need to understand how `confbw` (which is now 20, remember) is being translated into the actual channel width this system expects. I need to understand the relationship between this 20 value and the expected hardware configuration.
|
| 29/2 |
2026/05/17 19:06 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:hwsim_get_chanwidth]
Results: map[SourceCode: 991: static int hwsim_get_chanwidth(enum nl80211_chan_width bw)
992: {
993: switch (bw) {
994: case NL80211_CHAN_WIDTH_20_NOHT:
995: case NL80211_CHAN_WIDTH_20:
996: return 20;
997: case NL80211_CHAN_WIDTH_40:
998: return 40;
999: case NL80211_CHAN_WIDTH_80:
1000: return 80;
1001: case NL80211_CHAN_WIDTH_80P80:
1002: case NL80211_CHAN_WIDTH_160:
1003: return 160;
1004: case NL80211_CHAN_WIDTH_320:
1005: return 320;
1006: case NL80211_CHAN_WIDTH_5:
1007: return 5;
1008: case NL80211_CHAN_WIDTH_10:
1009: return 10;
1010: case NL80211_CHAN_WIDTH_1:
1011: return 1;
1012: case NL80211_CHAN_WIDTH_2:
1013: return 2;
1014: case NL80211_CHAN_WIDTH_4:
1015: return 4;
1016: case NL80211_CHAN_WIDTH_8:
1017: return 8;
1018: case NL80211_CHAN_WIDTH_16:
1019: return 16;
1020: }
1021:
1022: return INT_MAX;
1023: }
SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c]
|
| 30/2 |
2026/05/17 19:06 |
llm |
expert |
0m
Model:
Tokens:
input: 76978
output: 57
thoughts: 1225
Thoughts: **Analysis of the Bandwidth Warning in mac80211_hwsim**
Okay, let's break this down. This code snippet checks if a Station (STA) bandwidth (`bw`) is greater than the channel configuration bandwidth (`hwsim_get_chanwidth(confbw)`). If it is, a warning is printed. My initial thought is, is this just a cosmetic issue, or is there a chance of something more serious like memory corruption or a crash?
It's clear that in a production environment, `WARN` doesn't halt execution, just logs a message. So, no immediate crash. I need to dig deeper: could this warning lead to a Denial of Service (DoS)? Could it cause a resource exhaustion?
The code is in `mac80211_hwsim_sta_rc_update`. This function iterates through links. Crucially, the code doesn't *use* `bw` or `confbw` after the check. It's simply a sanity check and warning. It does nothing else if the condition is true.
This `mac80211_hwsim` is a simulated radio environment for testing. This *could* be exploited, but only to cause log spam. So, at most a minor DoS if it can be triggered repeatedly. But it's in a testing module, and generally, `WARN` has rate-limiting, so this doesn't seem like a critical vulnerability.
Now I need to consider who can trigger this. Can unprivileged users get to it? No, looking at the wider context, creating and setting up `hwsim` radios requires `CAP_NET_ADMIN` in the user namespace, through `HWSIM_CMD_REGISTER` and `NL80211_CMD_SET_INTERFACE`. A normal user canât do this. So it would be "UserNamespace: true" and "Unprivileged: false".
Ah, but what about a guest VM that interacts with a `mac80211_hwsim` running on the host via a virtio device? That is `VMGuestTrigger`. Let me check `hwsim_virtio_rx_work` in `mac80211_hwsim.c`.
|
| 31/2 |
2026/05/17 19:06 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:hwsim_virtio_rx_work]
Results: map[SourceCode:7105: static void hwsim_virtio_rx_work(struct work_struct *work)
7106: {
7107: struct virtqueue *vq;
7108: unsigned int len;
7109: struct sk_buff *skb;
7110: struct scatterlist sg[1];
7111: int err;
7112: unsigned long flags;
7113:
7114: spin_lock_irqsave(&hwsim_virtio_lock, flags);
7115: if (!hwsim_virtio_enabled)
7116: goto out_unlock;
7117:
7118: skb = virtqueue_get_buf(hwsim_vqs[HWSIM_VQ_RX], &len);
7119: if (!skb)
7120: goto out_unlock;
7121: spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
7122:
7123: skb->data = skb->head;
7124: skb_reset_tail_pointer(skb);
7125: skb_put(skb, len);
7126: hwsim_virtio_handle_cmd(skb);
7127:
7128: spin_lock_irqsave(&hwsim_virtio_lock, flags);
7129: if (!hwsim_virtio_enabled) {
7130: dev_kfree_skb_irq(skb);
7131: goto out_unlock;
7132: }
7133: vq = hwsim_vqs[HWSIM_VQ_RX];
7134: sg_init_one(sg, skb->head, skb_end_offset(skb));
7135: err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_ATOMIC);
7136: if (WARN(err, "virtqueue_add_inbuf returned %d\n", err))
7137: dev_kfree_skb_irq(skb);
7138: else
7139: virtqueue_kick(vq);
7140: schedule_work(&hwsim_virtio_rx);
7141:
7142: out_unlock:
7143: spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
7144: }
SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c]
|
| 32/2 |
2026/05/17 19:06 |
llm |
expert |
0m
Model:
Tokens:
input: 79438
output: 57
thoughts: 19
Thoughts: Okay, here's my attempt at summarizing the thought process, as if it were my own, assuming I'm an expert in this field:
**Handling Virtio Queue Commands: My Process**
Alright, let's break down this `hwsim_virtio_handle_cmd` function. My brain immediately clicks on the context: we're dealing with commands coming in from the virtio queue, specifically, those requests that are trying to interact with the simulated hardware within the hwsim environment. Essentially, this function is the central point where the "outside world," through the virtio interface, tells the simulated hardware what to do.
So, I know this is where the core logic resides for interpreting those commands. I immediately start thinking about how to parse the incoming command data. Iâll need to figure out the command type â is this a read, a write, a configuration update, or something else entirely? The command itself will likely be encoded in a particular format as defined by the virtio specification for the given device. From there, I'll need to dispatch to the appropriate handler, the correct routine to execute the request on the simulated hardware. This could involve memory access, device register manipulation, or even some form of device emulation.
I also can't forget about error handling. What happens if the command is malformed, if the requested memory address is invalid, or if the operation is otherwise impossible? Robust error handling is crucial for preventing crashes and maintaining the integrity of the simulation. I have to think about how to report these errors back to the virtio driver and ultimately to the guest OS, perhaps using specific virtio error codes or status flags.
And finally, I'm already anticipating the need for concurrency control. This function will likely be called from multiple threads, or at least in a potentially concurrent manner, so I have to be careful about protecting shared resources and ensuring data consistency. Locks, mutexes, and atomic operations might all be necessary. Let's see how they have implemented it.
|
| 33/2 |
2026/05/17 19:06 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:hwsim_virtio_handle_cmd]
Results: map[SourceCode:7065: static int hwsim_virtio_handle_cmd(struct sk_buff *skb)
7066: {
7067: struct nlmsghdr *nlh;
7068: struct genlmsghdr *gnlh;
7069: struct nlattr *tb[HWSIM_ATTR_MAX + 1];
7070: struct genl_info info = {};
7071: int err;
7072:
7073: nlh = nlmsg_hdr(skb);
7074: gnlh = nlmsg_data(nlh);
7075:
7076: if (skb->len < nlh->nlmsg_len)
7077: return -EINVAL;
7078:
7079: err = genlmsg_parse(nlh, &hwsim_genl_family, tb, HWSIM_ATTR_MAX,
7080: hwsim_genl_policy, NULL);
7081: if (err) {
7082: pr_err_ratelimited("hwsim: genlmsg_parse returned %d\n", err);
7083: return err;
7084: }
7085:
7086: info.attrs = tb;
7087:
7088: switch (gnlh->cmd) {
7089: case HWSIM_CMD_FRAME:
7090: hwsim_cloned_frame_received_nl(skb, &info);
7091: break;
7092: case HWSIM_CMD_TX_INFO_FRAME:
7093: hwsim_tx_info_frame_received_nl(skb, &info);
7094: break;
7095: case HWSIM_CMD_REPORT_PMSR:
7096: hwsim_pmsr_report_nl(skb, &info);
7097: break;
7098: default:
7099: pr_err_ratelimited("hwsim: invalid cmd: %d\n", gnlh->cmd);
7100: return -EPROTO;
7101: }
7102: return 0;
7103: }
SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c]
|
| 34/2 |
2026/05/17 19:06 |
llm |
expert |
0m
Model:
Tokens:
input: 80575
output: 55
thoughts: 267
Thoughts: **My Analysis of the `mac80211_hwsim` Virtio Interaction**
Okay, so I'm digging into how `mac80211_hwsim` interacts with virtio, and things are starting to click. I see that `hwsim_virtio_handle_cmd` processes the `HWSIM_CMD_FRAME` command specifically from the virtio queue â that's the entry point. Now, I need to understand the security implications.
Looking at `hwsim_cloned_frame_received_nl`, I notice a critical check:
```c
if (!hwsim_virtio_enabled) {
if (hwsim_net_get_netgroup(genl_info_net(info)) !=
data2->netgroup)
goto out;
if (info->snd_portid != data2->wmediumd)
goto out;
}
```
If `hwsim_virtio_enabled` is *false*, this code *does* enforce checks on the sender's port ID. However, if `hwsim_virtio_enabled` is *true*, the `snd_portid` check is *bypassed*! Hmm, that's interesting.
This immediately tells me that a VM guest, when `hwsim_virtio_enabled` is true, has the potential to inject frames directly into the host's `mac80211_hwsim`. That's a serious vulnerability in the right scenario.
Now, wait a minute... I need to clarify the role of `hwsim_virtio_probe`. I recall that this function is called when the *host* exposes a virtio device to the *guest*, and the *guest* then loads `mac80211_hwsim`. Hold on... the light bulb is flickering: `mac80211_hwsim` isn't a virtio *device*, it's actually a virtio *driver*! The host acts as the virtio device, and the guest runs the driver. Okay, that distinction is crucial. Time to take a closer look at `hwsim_virtio_probe` to solidify this understanding.
|
| 35/2 |
2026/05/17 19:06 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/net/wireless/virtual/mac80211_hwsim.c IncludeLines:true Name:hwsim_virtio_probe]
Results: map[SourceCode:7201: static int hwsim_virtio_probe(struct virtio_device *vdev)
7202: {
7203: int err;
7204: unsigned long flags;
7205:
7206: spin_lock_irqsave(&hwsim_virtio_lock, flags);
7207: if (hwsim_virtio_enabled) {
7208: spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
7209: return -EEXIST;
7210: }
7211: spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
7212:
7213: err = init_vqs(vdev);
7214: if (err)
7215: return err;
7216:
7217: virtio_device_ready(vdev);
7218:
7219: err = fill_vq(hwsim_vqs[HWSIM_VQ_RX]);
7220: if (err)
7221: goto out_remove;
7222:
7223: spin_lock_irqsave(&hwsim_virtio_lock, flags);
7224: hwsim_virtio_enabled = true;
7225: spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
7226:
7227: schedule_work(&hwsim_virtio_rx);
7228: return 0;
7229:
7230: out_remove:
7231: remove_vqs(vdev);
7232: return err;
7233: }
SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c]
|
| 36/2 |
2026/05/17 19:06 |
llm |
expert |
0m
Model:
Tokens:
input: 81882
output: 54
thoughts: 1062
Thoughts: **Analyzing the VM Host Trigger in a Confidential Computing Context**
Okay, let's break this down. My primary concern is whether a KVM host can trigger this bug within a confidential computing guest kernel. The key here seems to be the `mac80211_hwsim` module, which, as I see, registers itself as a virtio driver. This means that if a virtio device of type `VIRTIO_ID_MAC80211_HWSIM` is presented to the guest, the guest will load this driver. The guest is running `mac80211_hwsim`, the host provides the virtio device, so the host is sending frames to the guest via the virtio queue.
The prompt specifically asks about standard paravirtualized features. My immediate thought is, no, `mac80211_hwsim` is not a standard feature like `virtio-blk` or `virtio-net`. It's a testing tool. So, in the typical confidential computing setup, you *wouldn't* expect this module to be loaded. My initial gut feeling is that `VMHostTrigger` is false. However, it *is* possible for the host to send frames to the guest *if* the module is loaded. So, the question is really whether the host can trick the guest into loading it. And if so, can the host trigger the bug?
The bug's reproducer involves a userspace program sending netlink messages. This is the crucial point. The host can inject a malicious frame, in this case, a QoS data frame. The host sends a virtio message, which the guest processes via `hwsim_virtio_handle_cmd`, which then calls `hwsim_cloned_frame_received_nl`, which injects the frame. But the bug is in the `mac80211_hwsim_sta_rc_update` function, called when a station is added or updated.
The reproducer's steps are:
1. Create a netlink socket.
2. Send `NL80211_CMD_SET_INTERFACE` to set the interface type.
3. Send `NL80211_CMD_JOIN_OCB`.
4. Inject a frame using `HWSIM_CMD_FRAME`.
The provided frame content is the critical piece. Looking at the frame contents: `0x88` is the frame control field. In little-endian, it is `1000 1000`. This corresponds to `IEEE80211_STYPE_QOS_DATA`. Therefore it is a QoS Data frame. The bug is triggered when the QoS data frame is received.
The question then becomes, will receiving the QoS Data frame cause a new station to be added, triggering `mac80211_hwsim_sta_rc_update`? Especially in OCB mode, where stations are added automatically.
I need to review `net/mac80211/ocb.c` to confirm the station addition process in OCB mode.
|
| 37/2 |
2026/05/17 19:07 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/mac80211/ocb.c IncludeLines:true Name:ieee80211_ocb_work]
Results: map[SourceCode: 122: void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata)
123: {
124: struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
125: struct sta_info *sta;
126:
127: lockdep_assert_wiphy(sdata->local->hw.wiphy);
128:
129: if (ifocb->joined != true)
130: return;
131:
132: spin_lock_bh(&ifocb->incomplete_lock);
133: while (!list_empty(&ifocb->incomplete_stations)) {
134: sta = list_first_entry(&ifocb->incomplete_stations,
135: struct sta_info, list);
136: list_del(&sta->list);
137: spin_unlock_bh(&ifocb->incomplete_lock);
138:
139: ieee80211_ocb_finish_sta(sta);
140: rcu_read_unlock();
141: spin_lock_bh(&ifocb->incomplete_lock);
142: }
143: spin_unlock_bh(&ifocb->incomplete_lock);
144:
145: if (test_and_clear_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags))
146: ieee80211_ocb_housekeeping(sdata);
147: }
SourceFile:net/mac80211/ocb.c]
|
| 38/2 |
2026/05/17 19:07 |
llm |
expert |
0m
Model:
Tokens:
input: 84158
output: 33
thoughts: 1383
Thoughts: **Bug Analysis: mac80211_hwsim STA Bandwidth Warning**
Okay, let's break this down. In OCB mode, a new MAC address triggers the incomplete station process. The code path goes through a series of function calls: `ieee80211_ocb_finish_sta` to `mac80211_hwsim_sta_add`, which eventually calls `mac80211_hwsim_sta_rc_update`. This is where the warning is generated: `mac80211_hwsim.c:2832`. So, itâs specific to the `mac80211_hwsim` driver, not the core `mac80211` code.
The trigger? Receiving a frame in OCB mode. Can a host trigger this on a guest using, say, a virtio interface? Only if the guest has *first* configured its `mac80211_hwsim` interface in OCB mode, which requires `CAP_NET_ADMIN` through `NL80211_CMD_JOIN_OCB`. Thus, the host *cannot* trigger it on a default guest because the guest will not enable OCB mode by default. Therefore, `VMHostTrigger` is clearly false.
Regarding exploitability: It's just a `WARN`, not a crash or memory corruption, so `Exploitable` is `False`. The function simply prints a warning message and returns.
Denial of Service? At first glance, `False`. It's just a warning. In a production build where `panic_on_warn` is not set, it just prints. No kernel halt, hang, or resource leak. However, a closer look suggests that it could cause log spam by repeatedly sending frames from different MAC addresses in OCB mode, thus repeatedly triggering the `WARN`. This would create many stations and cause repeated warnings. Although `WARN` isn't rate-limited (unlike `WARN_ONCE`), this log spam, while not a full DoS leading to system hang or resource exhaustion, *could* be considered a minor form of DoS. Thus, I'll mark `Denial Of Service` as `False`, but I'll make sure to note the log spam possibility in my reasoning.
The accessibility dimensions: Unprivileged processes cannot trigger it, requiring `CAP_NET_ADMIN` to configure OCB mode and register the hwsim socket, so `Accessible From Unprivileged Processes` is `False`. However, a user namespace with the necessary capabilities *can* trigger it, so `Accessible From User Namespaces` is `True`.
Other triggers? No remote network trigger, no peripheral trigger, and no malicious filesystem trigger. It's a simulated radio, so real-world network attacks aren't relevant.
Now, let's revisit DoS more carefully based on the prompt. The assumption violation here is that the station's bandwidth (`bw`) should not exceed the channel's bandwidth (`hwsim_get_chanwidth(confbw)`). The code just warns; there's no error return or state change. The question is, does the violation have any real consequence in this particular function or elsewhere? The function in question just prints the warning. The code doesn't use the potentially problematic bandwidth value (`bw`) further within this function. I'll need to check how `bw` is used elsewhere in `mac80211_hwsim` to get a full picture of the impact.
|
| 39/2 |
2026/05/17 19:07 |
tool |
codesearch-find-references |
0m
Args: map[Name:mac80211_hwsim_sta_rc_update]
Results: map[References:[map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:mac80211_hwsim_sta_add SourceFile:drivers/net/wireless/virtual/mac80211_hwsim.c SourceLine:2849]] TruncatedOutput:false]
|
| 40/2 |
2026/05/17 19:07 |
llm |
expert |
0m
Model:
Tokens:
input: 86415
output: 56
thoughts: 1472
Thoughts: **Analyzing the Impact of a Bandwidth Assumption Violation in mac80211_hwsim**
Okay, so I'm looking at this `mac80211_hwsim_sta_rc_update` function, and it seems like it's only called from `mac80211_hwsim_sta_add`. The add function just calls the update and returns. There's no other consequence within the driver itself. Since `mac80211_hwsim` is a simulation, bandwidth isn't really a concern; it just models the radio. This warning was likely put there to catch potential issues in the core `mac80211` code where it *might* pass bad bandwidth values to the driver. So, the violation of this assumption doesn't cause any denial-of-service in this context.
Now, I need to check if unprivileged processes can access `mac80211_hwsim` again. We know `HWSIM_CMD_REGISTER` needs `CAP_NET_ADMIN` in the user namespace. Are there other ways to inject frames? `HWSIM_CMD_FRAME` doesn't need that capability, but it calls `hwsim_cloned_frame_received_nl`. This function checks: if `hwsim_virtio_enabled` is false, it verifies that the sender's port ID (`info->snd_portid`) matches `data2->wmediumd`. `data2->wmediumd` gets set in `hwsim_register_received_nl`, which handles `HWSIM_CMD_REGISTER`, which requires `CAP_NET_ADMIN`. So, unprivileged processes can't set their port ID as the valid one, because they can't register. Therefore, they can't inject frames using `HWSIM_CMD_FRAME`.
Wait, what if `wmediumd` is 0? If no one has registered, it *would* be zero. But can the sender's port ID, `info->snd_portid`, *be* 0? No, that's reserved for the kernel. For user space sockets, the port ID is the process's PID or a random number if the PID is already in use. So, `info->snd_portid != 0` is always true for userspace. Thus, unprivileged processes *still* can't inject frames even if `wmediumd` is 0.
Wait, is there *another* way to trigger the bug? The bug happens when a station is added. In OCB mode, stations are added automatically when frames are received. Can an unprivileged process send a frame over a normal network interface that gets processed by `mac80211` and triggers station addition? If the interface is in OCB, it can receive frames from the air. But `mac80211_hwsim` is a simulated radio. It only receives frames from other `mac80211_hwsim` radios or via the HWSIM commands or virtio. If there are two `mac80211_hwsim` radios, and one sends a frame, the other receives it. Can an unprivileged process send a frame through radio 1, and have it received by radio 2? To send, they'd need a raw packet socket (`AF_PACKET`) but that needs `CAP_NET_RAW`, which unprivileged users don't have. Can they send a *normal* UDP/TCP packet that gets encapsulated in an 802.11 frame and sent by radio 1? Yes, if radio 1 is configured as an AP or STA and is connected to a network, normal network traffic *will* be sent over it. The bug is triggered by *receiving* the frame in OCB. If radio 2 is in OCB, it will receive the frame. But wait, to configure radio 2 in OCB, you need `CAP_NET_ADMIN`.
Okay, what if the system administrator has already configured radio 2 in OCB, and radio 1 is also configured appropriately? An unprivileged process sends a UDP packet, radio 1 transmits an 802.11 frame, and radio 2 receives it. Radio 2 receives the frame; if the source MAC is unknown, it adds a station. But the source MAC would be radio 1's MAC, which is likely already known. Okay, when it gets added, `mac80211_hwsim_sta_rc_update` is called. Will it trigger the WARN? The WARN fires if `bw > hwsim_get_chanwidth(confbw)`. `bw` comes from `sta->deflink.bandwidth`. When a station is added in O
|
| 41/2 |
2026/05/17 19:07 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/mac80211/ocb.c IncludeLines:true Name:ieee80211_ocb_finish_sta]
Results: map[SourceCode: 87: static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta)
88: __acquires(RCU)
89: {
90: struct ieee80211_sub_if_data *sdata = sta->sdata;
91: u8 addr[ETH_ALEN];
92:
93: memcpy(addr, sta->sta.addr, ETH_ALEN);
94:
95: ocb_dbg(sdata, "Adding new IBSS station %pM (dev=%s)\n",
96: addr, sdata->name);
97:
98: sta_info_move_state(sta, IEEE80211_STA_AUTH);
99: sta_info_move_state(sta, IEEE80211_STA_ASSOC);
100: sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
101:
102: rate_control_rate_init(&sta->deflink);
103:
104: /* If it fails, maybe we raced another insertion? */
105: if (sta_info_insert_rcu(sta))
106: return sta_info_get(sdata, addr);
107: return sta;
108: }
SourceFile:net/mac80211/ocb.c]
|
| 42/2 |
2026/05/17 19:07 |
llm |
expert |
0m
Model:
Tokens:
input: 89376
output: 48
thoughts: 16
Thoughts: Here's a summary of my understanding, framed from my perspective as an expert:
**Understanding the Initialization of `sta->deflink`**
Okay, so I'm looking at `rate_control_rate_init`. From what I'm seeing, this routine is the first step in setting up the data structure, `sta->deflink`. Right, so it's the initialization, the foundation for the specific rate control mechanism this station (`sta`) will employ. This suggests that the code is structured in a modular manner, where the link-specific aspects, like link adaptation data (`deflink`) are decoupled from the overall wireless driver's operational flow. The `deflink` is a key structure, since this is used by the rate control algorithms. Getting it initialized is critical, therefore, to correctly manage the wireless communications for this station. I'll need to dig into `rate_control_rate_init` to understand *how* it initializes `sta->deflink`, what default values or initial states are assigned, and whether it performs any memory allocation or resource setup related to `deflink`. Understanding the initialization process is fundamental for debugging or modifying rate control strategies later on.
|
| 43/2 |
2026/05/17 19:07 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/mac80211/rate.c IncludeLines:true Name:rate_control_rate_init]
Results: map[SourceCode: 31: void rate_control_rate_init(struct link_sta_info *link_sta)
32: {
33: struct sta_info *sta = link_sta->sta;
34: struct ieee80211_local *local = sta->sdata->local;
35: struct rate_control_ref *ref = sta->rate_ctrl;
36: struct ieee80211_sta *ista = &sta->sta;
37: void *priv_sta = sta->rate_ctrl_priv;
38: struct ieee80211_supported_band *sband;
39: struct ieee80211_chanctx_conf *chanctx_conf;
40:
41: ieee80211_sta_init_nss(link_sta);
42:
43: if (!ref)
44: return;
45:
46: /* SW rate control isn't supported with MLO right now */
47: if (WARN_ON(ieee80211_vif_is_mld(&sta->sdata->vif)))
48: return;
49:
50: rcu_read_lock();
51:
52: chanctx_conf = rcu_dereference(sta->sdata->vif.bss_conf.chanctx_conf);
53: if (WARN_ON(!chanctx_conf)) {
54: rcu_read_unlock();
55: return;
56: }
57:
58: sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
59:
60: /* TODO: check for minstrel_s1g ? */
61: if (sband->band == NL80211_BAND_S1GHZ) {
62: ieee80211_s1g_sta_rate_init(sta);
63: rcu_read_unlock();
64: return;
65: }
66:
67: spin_lock_bh(&sta->rate_ctrl_lock);
68: ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
69: priv_sta);
70: spin_unlock_bh(&sta->rate_ctrl_lock);
71: rcu_read_unlock();
72: set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
73: }
SourceFile:net/mac80211/rate.c]
|
| 44/2 |
2026/05/17 19:07 |
llm |
expert |
0m
Model:
Tokens:
input: 90415
output: 15
thoughts: 1534
Thoughts: **Analysis of the Bandwidth Warning in mac80211_hwsim**
Okay, let's break this down. It seems the core issue revolves around a bandwidth comparison within the `mac80211_hwsim` module, specifically the warning triggered when the station's bandwidth (`sta->deflink.bandwidth`, which defaults to 20 MHz or `IEEE80211_STA_RX_BW_20` due to `kzalloc`) exceeds the configured channel bandwidth (`hwsim_get_chanwidth(confbw)`). The crux of the problem lies in an OCB interface configured on a 10 MHz channel, which causes the warning when it receives a frame, adds a station, and triggers the bandwidth check.
First, I assessed whether this is a "Network Trigger." The prompt explicitly asks if this can be triggered by network traffic. While the OCB interface *receives* traffic, it is within the *simulated* `mac80211_hwsim`. This is not a real-world network interface. Therefore, even though the bug is related to "ingress network Ethernet traffic", it is not triggered by the network stack. So, `NetworkTrigger` is `false`.
Next, I determined if the bug is `Exploitable`. I confirmed that the code merely generates a `WARN` message. There's no crash, no memory corruption â just a warning. So, the bug is not exploitable, thus `Exploitable` is `false`.
Regarding `UserNamespace`, the reproducer utilizes `syz_genetlink_get_family_id` to obtain the `MAC80211_HWSIM` family ID and subsequently uses `syz_80211_inject_frame` which calls `hwsim_register_socket` using the family ID to establish the socket. These operations rely on `HWSIM_CMD_REGISTER`, which necessitates `GENL_UNS_ADMIN_PERM`. However, the netlink family `MAC80211_HWSIM` has `.netnsok = true`. In a user namespace, if the process has `CAP_NET_ADMIN`, it can register a `mac80211_hwsim` socket. The reproducer also involves `NL80211_CMD_SET_INTERFACE` and `NL80211_CMD_JOIN_OCB`, which are also permissible within a network namespace. Consequently, a process running within a user namespace can trigger the bug, so `UserNamespace` is definitively `true`.
I also considered whether `mac80211_hwsim` could be autoloaded. This is key because if the module is not already loaded, the bug is inaccessible. But it has an alias, `MODULE_ALIAS_GENL_FAMILY("MAC80211_HWSIM")`. Thus, the module can be autoloaded. An unprivileged process in a user namespace can trigger an autoload. This reinforces the correctness of `UserNamespace: true`.
Finally, the prompt asks about `DenialOfService`. While the code triggers a warning, it does not lead to crashes or system failures. Although the condition `bw > hwsim_get_chanwidth(confbw)` is not explicitly handled in `mac80211_hwsim`, the warning itself doesn't cause a DoS by itself. I have also verified that the bandwidth (`sta->deflink.bandwidth`) is not used elsewhere. So, the code just warns, but the condition does not result in any immediate denial of service. Thus `DenialOfService` is `false`.
Therefore, the final assessment is:
* Exploitable: `false`
* DenialOfService: `false`
* Unprivileged: `false`
* UserNamespace: `true`
* VMGuestTrigger: `false`
* VMHostTrigger: `false`
* NetworkTrigger: `false`
* RemoteTrigger: `false`
* PeripheralTrigger: `false`
* FilesystemTrigger: `false`
|
| 45/2 |
2026/05/17 19:08 |
tool |
grepper |
0m
Args: map[Expression:bandwidth]
Results: map[Output:
Full output is too long, showing 500 out of 37628 lines.
Use more precise expression if possible.
[Documentation/.renames.txt=413=media/uapi/dvb/examples userspace-api/media/dvb/examples
Documentation/.renames.txt:414:media/uapi/dvb/fe-bandwidth-t userspace-api/media/dvb/fe-bandwidth-t
Documentation/.renames.txt-415-media/uapi/dvb/fe-diseqc-recv-slave-reply userspace-api/media/dvb/fe-diseqc-recv-slave-reply
--
Documentation/ABI/removed/sysfs-kernel-uids=5=Description:
Documentation/ABI/removed/sysfs-kernel-uids-6- The /sys/kernel/uids/<uid>/cpu_shares tunable is used
Documentation/ABI/removed/sysfs-kernel-uids:7: to set the cpu bandwidth a user is allowed. This is a
Documentation/ABI/removed/sysfs-kernel-uids-8- proportional value. What that means is that if there
Documentation/ABI/removed/sysfs-kernel-uids-9- are two users logged in, each with an equal number of
Documentation/ABI/removed/sysfs-kernel-uids:10: shares, then they will get equal CPU bandwidth. Another
Documentation/ABI/removed/sysfs-kernel-uids-11- example would be, if User A has shares = 1024 and user
Documentation/ABI/removed/sysfs-kernel-uids-12- B has shares = 2048, User B will get twice the CPU
Documentation/ABI/removed/sysfs-kernel-uids:13: bandwidth user A will. For more details refer
Documentation/ABI/removed/sysfs-kernel-uids-14- Documentation/scheduler/sched-design-CFS.rst
--
Documentation/ABI/stable/firewire-cdev=5=Description:
--
Documentation/ABI/stable/firewire-cdev-32- - Allocate, reallocate, deallocate isochronous
Documentation/ABI/stable/firewire-cdev:33: resources (channels, bandwidth) at the bus's IRM
Documentation/ABI/stable/firewire-cdev-34- - Query node IDs of local node, root node, IRM, bus
--
Documentation/ABI/stable/firewire-cdev-104- nodes' Configuration ROM. Deallocate isochronous channels and
Documentation/ABI/stable/firewire-cdev:105: bandwidth at the IRM that were marked for kernel-assisted
Documentation/ABI/stable/firewire-cdev-106- re- and deallocation.
--
Documentation/ABI/stable/sysfs-devices-node=114=Description:
--
Documentation/ABI/stable/sysfs-devices-node-117-
Documentation/ABI/stable/sysfs-devices-node:118:What: /sys/devices/system/node/nodeX/accessY/initiators/read_bandwidth
Documentation/ABI/stable/sysfs-devices-node-119-Date: December 2018
--
Documentation/ABI/stable/sysfs-devices-node=121=Description:
Documentation/ABI/stable/sysfs-devices-node:122: This node's read bandwidth in MB/s when accessed from
Documentation/ABI/stable/sysfs-devices-node-123- nodes found in this access class's linked initiators.
--
Documentation/ABI/stable/sysfs-devices-node=128=Description:
--
Documentation/ABI/stable/sysfs-devices-node-131-
Documentation/ABI/stable/sysfs-devices-node:132:What: /sys/devices/system/node/nodeX/accessY/initiators/write_bandwidth
Documentation/ABI/stable/sysfs-devices-node-133-Date: December 2018
--
Documentation/ABI/stable/sysfs-devices-node=135=Description:
Documentation/ABI/stable/sysfs-devices-node:136: This node's write bandwidth in MB/s when accessed from
Documentation/ABI/stable/sysfs-devices-node-137- found in this access class's linked initiators.
--
Documentation/ABI/stable/sysfs-driver-dma-idxd=125=Description: The maximum number of read buffers that may be in use at
Documentation/ABI/stable/sysfs-driver-dma-idxd:126: one time by operations that access low bandwidth memory in the
Documentation/ABI/stable/sysfs-driver-dma-idxd-127- device. See DSA spec v1.2 9.2.8 GENCFG on Global Read Buffer Limit.
--
Documentation/ABI/testing/configfs-usb-gadget-uac2=4=Description:
--
Documentation/ABI/testing/configfs-usb-gadget-uac2-21- (in 1/256 dB)
Documentation/ABI/testing/configfs-usb-gadget-uac2:22: fb_max maximum extra bandwidth in async mode
Documentation/ABI/testing/configfs-usb-gadget-uac2-23- p_chmask playback channel mask
--
Documentation/ABI/testing/debugfs-driver-qat_telemetry=41=Description: (RO) Reports device telemetry counters.
--
Documentation/ABI/testing/debugfs-driver-qat_telemetry-57- gp_lat_acc_avg average get to put latency [ns]
Documentation/ABI/testing/debugfs-driver-qat_telemetry:58: bw_in PCIe, write bandwidth [Mbps]
Documentation/ABI/testing/debugfs-driver-qat_telemetry:59: bw_out PCIe, read bandwidth [Mbps]
Documentation/ABI/testing/debugfs-driver-qat_telemetry-60- re_acc_avg average ring empty time [ns]
--
Documentation/ABI/testing/debugfs-driver-qat_telemetry=140=Description: (RW) Selects up to 4 Ring Pairs (RP) to monitor, one per file,
--
Documentation/ABI/testing/debugfs-driver-qat_telemetry-162- gp_lat_acc_avg average get to put latency [ns]
Documentation/ABI/testing/debugfs-driver-qat_telemetry:163: bw_in PCIe, write bandwidth [Mbps]
Documentation/ABI/testing/debugfs-driver-qat_telemetry:164: bw_out PCIe, read bandwidth [Mbps]
Documentation/ABI/testing/debugfs-driver-qat_telemetry-165- at_glob_devtlb_hit Message descriptor DevTLB hit rate
--
Documentation/ABI/testing/debugfs-hisi-hpre=55=Contact: linux-crypto@vger.kernel.org
Documentation/ABI/testing/debugfs-hisi-hpre:56:Description: Query the real-time bandwidth usage of device.
Documentation/ABI/testing/debugfs-hisi-hpre:57: Returns the bandwidth usage of each channel on the device.
Documentation/ABI/testing/debugfs-hisi-hpre-58- The returned number is in percentage.
--
Documentation/ABI/testing/debugfs-hisi-sec=29=Contact: linux-crypto@vger.kernel.org
Documentation/ABI/testing/debugfs-hisi-sec:30:Description: Query the real-time bandwidth usage of device.
Documentation/ABI/testing/debugfs-hisi-sec:31: Returns the bandwidth usage of each channel on the device.
Documentation/ABI/testing/debugfs-hisi-sec-32- The returned number is in percentage.
--
Documentation/ABI/testing/debugfs-hisi-zip=41=Contact: linux-crypto@vger.kernel.org
Documentation/ABI/testing/debugfs-hisi-zip:42:Description: Query the real-time bandwidth usage of device.
Documentation/ABI/testing/debugfs-hisi-zip:43: Returns the bandwidth usage of each channel on the device.
Documentation/ABI/testing/debugfs-hisi-zip-44- The returned number is in percentage.
--
Documentation/ABI/testing/sysfs-bus-cxl=573=Description:
--
Documentation/ABI/testing/sysfs-bus-cxl-582-
Documentation/ABI/testing/sysfs-bus-cxl:583:What: /sys/bus/cxl/devices/regionZ/accessY/read_bandwidth
Documentation/ABI/testing/sysfs-bus-cxl:584: /sys/bus/cxl/devices/regionZ/accessY/write_bandwidth
Documentation/ABI/testing/sysfs-bus-cxl-585-Date: Jan, 2024
--
Documentation/ABI/testing/sysfs-bus-cxl=588=Description:
Documentation/ABI/testing/sysfs-bus-cxl:589: (RO) The aggregated read or write bandwidth of the region. The
Documentation/ABI/testing/sysfs-bus-cxl:590: number is the accumulated read or write bandwidth of all CXL memory
Documentation/ABI/testing/sysfs-bus-cxl-591- devices that contributes to the region in MB/s. It is
Documentation/ABI/testing/sysfs-bus-cxl-592- identical data that should appear in
Documentation/ABI/testing/sysfs-bus-cxl:593: /sys/devices/system/node/nodeX/accessY/initiators/read_bandwidth or
Documentation/ABI/testing/sysfs-bus-cxl:594: /sys/devices/system/node/nodeX/accessY/initiators/write_bandwidth.
Documentation/ABI/testing/sysfs-bus-cxl-595- See Documentation/ABI/stable/sysfs-devices-node. access0 provides
--
Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc=5=Description:
--
Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc-11- Writing '1' will remove the polling for the Conversion Ready Flags to
Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc:12: save the additional i2c transaction, which will improve the bandwidth
Documentation/ABI/testing/sysfs-bus-iio-ina2xx-adc-13- available for reading data. However, samples can be occasionally skipped
--
Documentation/ABI/testing/sysfs-bus-most=133=Users:
Documentation/ABI/testing/sysfs-bus-most-134-
Documentation/ABI/testing/sysfs-bus-most:135:What: /sys/bus/most/devices/<dev>/dci/packet_bandwidth
Documentation/ABI/testing/sysfs-bus-most-136-Date: June 2016
--
Documentation/ABI/testing/sysfs-bus-most=139=Description:
Documentation/ABI/testing/sysfs-bus-most:140: Indicates the configured packet bandwidth.
Documentation/ABI/testing/sysfs-bus-most-141-Users:
--
Documentation/ABI/testing/sysfs-class-intel_pmt-features=37=Additional Attributes (Conditional Presence):
--
Documentation/ABI/testing/sysfs-class-intel_pmt-features-60- RMIDs are identifiers used by hardware to track and report resource usage,
Documentation/ABI/testing/sysfs-class-intel_pmt-features:61: such as memory bandwidth or energy consumption, on a per-logical-entity
Documentation/ABI/testing/sysfs-class-intel_pmt-features-62- basis (e.g., per core, thread, or process group).
--
Documentation/ABI/testing/sysfs-class-net-cdc_ncm=5=Description:
--
Documentation/ABI/testing/sysfs-class-net-cdc_ncm-16- interrupts in the device, and represents a tradeoff
Documentation/ABI/testing/sysfs-class-net-cdc_ncm:17: between USB bus bandwidth and device DMA optimization.
Documentation/ABI/testing/sysfs-class-net-cdc_ncm-18-
--
Documentation/ABI/testing/sysfs-devices-edac=69=Description: Read/Write attribute file that controls memory scrubbing.
Documentation/ABI/testing/sysfs-devices-edac-70- The scrubbing rate used by the memory controller is set by
Documentation/ABI/testing/sysfs-devices-edac:71: writing a minimum bandwidth in bytes/sec to the attribute file.
Documentation/ABI/testing/sysfs-devices-edac-72- The rate will be translated to an internal value that gives at
--
Documentation/ABI/testing/sysfs-devices-platform-soc-ipa=82=Description:
--
Documentation/ABI/testing/sysfs-devices-platform-soc-ipa-88- header (see .../XXXXXXX.ipa/feature/monitor, above).
Documentation/ABI/testing/sysfs-devices-platform-soc-ipa:89: Large packets are truncated, to reduce the bandwidth
Documentation/ABI/testing/sysfs-devices-platform-soc-ipa-90- required to provide the monitor function.
--
Documentation/ABI/testing/sysfs-kernel-mm-mempolicy-weighted-interleave=32=Description: Auto-weighting configuration interface
--
Documentation/ABI/testing/sysfs-kernel-mm-mempolicy-weighted-interleave-38- In auto mode, all node weights are re-calculated and overwritten
Documentation/ABI/testing/sysfs-kernel-mm-mempolicy-weighted-interleave:39: (visible via the nodeN interfaces) whenever new bandwidth data
Documentation/ABI/testing/sysfs-kernel-mm-mempolicy-weighted-interleave-40- is made available during either boot or hotplug events.
--
Documentation/ABI/testing/sysfs-kernel-mm-mempolicy-weighted-interleave-44- will reuse those weights. If they were not previously set or
Documentation/ABI/testing/sysfs-kernel-mm-mempolicy-weighted-interleave:45: are onlined with missing bandwidth data, the weights will use
Documentation/ABI/testing/sysfs-kernel-mm-mempolicy-weighted-interleave-46- a default weight of 1.
--
Documentation/ABI/testing/sysfs-module=18=Description: Maximum time allowed for periodic transfers per microframe (Ξs)
--
Documentation/ABI/testing/sysfs-module-24-
Documentation/ABI/testing/sysfs-module:25: However there are cases, when 80% max isochronous bandwidth is
Documentation/ABI/testing/sysfs-module-26- too limiting. For example two video streams could require 110
Documentation/ABI/testing/sysfs-module:27: microseconds of isochronous bandwidth per microframe to work
Documentation/ABI/testing/sysfs-module-28- together.
--
Documentation/ABI/testing/sysfs-module-31- the host controller would allow allocating more than 100
Documentation/ABI/testing/sysfs-module:32: microseconds of periodic bandwidth per microframe.
Documentation/ABI/testing/sysfs-module-33-
--
Documentation/accel/amdxdna/amdnpu.rst=81=NPU is visible to the x86 host CPU as a PCIe device with multiple BARs and some
Documentation/accel/amdxdna/amdnpu.rst:82:MSI-X interrupt vectors. NPU uses a dedicated high bandwidth SoC level fabric
Documentation/accel/amdxdna/amdnpu.rst-83-for reading or writing into host memory. Each instance of ERT gets its own
--
Documentation/admin-guide/RAS/main.rst=647=Module parameters
--
Documentation/admin-guide/RAS/main.rst-706- locating the error. 1000 milliseconds (once each second) is the current
Documentation/admin-guide/RAS/main.rst:707: default. Systems which require all the bandwidth they can get, may
Documentation/admin-guide/RAS/main.rst-708- increase this.
--
Documentation/admin-guide/cgroup-v1/blkio-controller.rst=31=Mount blkio controller (see cgroups.txt, Why are cgroups needed?)::
--
Documentation/admin-guide/cgroup-v1/blkio-controller.rst-34-
Documentation/admin-guide/cgroup-v1/blkio-controller.rst:35:Specify a bandwidth rate on particular device for root group. The format
Documentation/admin-guide/cgroup-v1/blkio-controller.rst-36-for policy is "<major>:<minor> <bytes_per_second>"::
--
Documentation/admin-guide/cgroup-v2.rst=1097=The "cpu" controllers regulates distribution of CPU cycles. This
Documentation/admin-guide/cgroup-v2.rst:1098:controller implements weight and absolute bandwidth limit models for
Documentation/admin-guide/cgroup-v2.rst:1099:normal scheduling policy and absolute bandwidth allocation model for
Documentation/admin-guide/cgroup-v2.rst-1100-realtime scheduling policy.
--
Documentation/admin-guide/cgroup-v2.rst=1107=be exceeded by a CPU.
Documentation/admin-guide/cgroup-v2.rst-1108-
Documentation/admin-guide/cgroup-v2.rst:1109:WARNING: cgroup2 cpu controller doesn't yet support the (bandwidth) control of
Documentation/admin-guide/cgroup-v2.rst-1110-realtime processes. For a kernel built with the CONFIG_RT_GROUP_SCHED option
--
Documentation/admin-guide/cgroup-v2.rst=1141=will be referred to. All time durations are in microseconds.
--
Documentation/admin-guide/cgroup-v2.rst-1196-
Documentation/admin-guide/cgroup-v2.rst:1197: The maximum bandwidth limit. It's in the following format::
Documentation/admin-guide/cgroup-v2.rst-1198-
--
Documentation/admin-guide/cgroup-v2.rst=1985=The "io" controller regulates the distribution of IO resources. This
Documentation/admin-guide/cgroup-v2.rst:1986:controller implements both weight based and absolute bandwidth or IOPS
Documentation/admin-guide/cgroup-v2.rst-1987-limit distribution; however, weight based distribution is available
--
Documentation/admin-guide/cgroup-v2.rst=1992=IO Interface Files
--
Documentation/admin-guide/cgroup-v2.rst-2053- The lower the saturation point, the better the latency QoS at
Documentation/admin-guide/cgroup-v2.rst:2054: the cost of aggregate bandwidth. The narrower the allowed
Documentation/admin-guide/cgroup-v2.rst-2055- adjustment range between "min" and "max", the more conformant
--
Documentation/admin-guide/cpu-isolation.rst=26=those kinds of noise. This is the case, for example, with high
Documentation/admin-guide/cpu-isolation.rst:27:bandwidth network processing that can't afford losing a single packet
Documentation/admin-guide/cpu-isolation.rst-28-or very low latency network processing. Typically those use cases
--
Documentation/admin-guide/device-mapper/cache.rst=118=Migration throttling
--
Documentation/admin-guide/device-mapper/cache.rst-120-
Documentation/admin-guide/device-mapper/cache.rst:121:Migrating data between the origin and cache device uses bandwidth.
Documentation/admin-guide/device-mapper/cache.rst-122-The user can set a throttle to prevent more than a certain amount of
--
Documentation/admin-guide/device-mapper/dm-clone.rst=104=all of the device has been copied.
Documentation/admin-guide/device-mapper/dm-clone.rst-105-
Documentation/admin-guide/device-mapper/dm-clone.rst:106:Copying data from the source to the destination device uses bandwidth. The user
Documentation/admin-guide/device-mapper/dm-clone.rst-107-can set a throttle to prevent more than a certain amount of copying occurring at
--
Documentation/admin-guide/device-mapper/switch.rst=36=interfaces on both the host and target to take advantage of the
Documentation/admin-guide/device-mapper/switch.rst:37:increased network bandwidth. An initiator could use a simple round
Documentation/admin-guide/device-mapper/switch.rst-38-robin algorithm to send I/O across all paths and let the storage array
--
Documentation/admin-guide/hw-vuln/special-register-buffer-data-sampling.rst=74=This has three effects on performance:
--
Documentation/admin-guide/hw-vuln/special-register-buffer-data-sampling.rst-79- serialized, resulting in an overall reduction in the maximum RDRAND
Documentation/admin-guide/hw-vuln/special-register-buffer-data-sampling.rst:80: bandwidth.
Documentation/admin-guide/hw-vuln/special-register-buffer-data-sampling.rst-81-
--
Documentation/admin-guide/hw-vuln/spectre.rst=79=over the network, see :ref:`[12] <spec_ref12>`. However such attacks
Documentation/admin-guide/hw-vuln/spectre.rst:80:are difficult, low bandwidth, fragile, and are considered low risk.
Documentation/admin-guide/hw-vuln/spectre.rst-81-
--
Documentation/admin-guide/media/ipu3.rst=246=high quality images. Besides, "STILL" mode need XNR3 to do noise reduction,
Documentation/admin-guide/media/ipu3.rst:247:hence "STILL" mode will need more power and memory bandwidth than "VIDEO" mode.
Documentation/admin-guide/media/ipu3.rst-248-TNR will be enabled in "VIDEO" mode and bypassed by "STILL" mode. ImgU is
--
Documentation/admin-guide/media/philips.rst=39=contains decompression routines that allow you to use higher image sizes and
Documentation/admin-guide/media/philips.rst:40:framerates; in addition the webcam uses less bandwidth on the USB bus (handy
Documentation/admin-guide/media/philips.rst-41-if you want to run more than 1 camera simultaneously). These routines fall
--
Documentation/admin-guide/media/philips.rst=95=compression (only useful with the plugin)
--
Documentation/admin-guide/media/philips.rst-106-
Documentation/admin-guide/media/philips.rst:107: High compression takes less bandwidth of course, but it could also
Documentation/admin-guide/media/philips.rst-108- introduce some unwanted artefacts. The default is 2, medium compression.
--
Documentation/admin-guide/media/si476x.rst=29=The drivers exposes following files:
--
Documentation/admin-guide/media/si476x.rst-47- 0x03 chbw_int Flag, set when channel filter
Documentation/admin-guide/media/si476x.rst:48: bandwidth is less than threshold
Documentation/admin-guide/media/si476x.rst-49- 0x04 softmute_int Flag indicating that softmute
--
Documentation/admin-guide/media/si476x.rst-54- 0x06 smattn Soft mute attenuation level in dB
Documentation/admin-guide/media/si476x.rst:55: 0x07 chbw Channel filter bandwidth in kHz
Documentation/admin-guide/media/si476x.rst-56- 0x08 hicut HiCut cutoff frequency in units of
--
Documentation/admin-guide/mm/damon/stat.rst=10=access monitoring results statistics, namely idle time percentiles and
Documentation/admin-guide/mm/damon/stat.rst:11:estimated memory bandwidth.
Documentation/admin-guide/mm/damon/stat.rst-12-
--
Documentation/admin-guide/mm/damon/stat.rst=63=dynamically changed.
Documentation/admin-guide/mm/damon/stat.rst-64-
Documentation/admin-guide/mm/damon/stat.rst:65:estimated_memory_bandwidth
Documentation/admin-guide/mm/damon/stat.rst-66---------------------------
Documentation/admin-guide/mm/damon/stat.rst-67-
Documentation/admin-guide/mm/damon/stat.rst:68:Estimated memory bandwidth consumption (bytes per second) of the system.
Documentation/admin-guide/mm/damon/stat.rst-69-
Documentation/admin-guide/mm/damon/stat.rst=70=DAMON_STAT reads observed access events on the current DAMON results snapshot
Documentation/admin-guide/mm/damon/stat.rst:71:and converts it to memory bandwidth consumption estimation in bytes per second.
Documentation/admin-guide/mm/damon/stat.rst-72-The resulting metric is exposed to user via this read-only parameter. Because
Documentation/admin-guide/mm/damon/stat.rst=73=DAMON uses sampling, this is only an estimation of the access intensity rather
Documentation/admin-guide/mm/damon/stat.rst:74:than accurate memory bandwidth.
Documentation/admin-guide/mm/damon/stat.rst-75-
--
Documentation/admin-guide/mm/numaperf.rst=10=as CPU cache coherence, but may have different performance. For example,
Documentation/admin-guide/mm/numaperf.rst:11:different media types and buses affect bandwidth and latency.
Documentation/admin-guide/mm/numaperf.rst-12-
--
Documentation/admin-guide/mm/numaperf.rst=80=are exported are as follows::
--
Documentation/admin-guide/mm/numaperf.rst-83- /sys/devices/system/node/nodeY/access0/initiators/
Documentation/admin-guide/mm/numaperf.rst:84: |-- read_bandwidth
Documentation/admin-guide/mm/numaperf.rst-85- |-- read_latency
Documentation/admin-guide/mm/numaperf.rst:86: |-- write_bandwidth
Documentation/admin-guide/mm/numaperf.rst-87- `-- write_latency
Documentation/admin-guide/mm/numaperf.rst-88-
Documentation/admin-guide/mm/numaperf.rst:89:The bandwidth attributes are provided in MiB/second.
Documentation/admin-guide/mm/numaperf.rst-90-
Documentation/admin-guide/mm/numaperf.rst=91=The latency attributes are provided in nanoseconds.
Documentation/admin-guide/mm/numaperf.rst-92-
Documentation/admin-guide/mm/numaperf.rst:93:The values reported here correspond to the rated latency and bandwidth
Documentation/admin-guide/mm/numaperf.rst-94-for the platform.
--
Documentation/admin-guide/nfs/nfs-rdma.rst=20=In our testing, we have obtained excellent performance results (full 10Gbit
Documentation/admin-guide/nfs/nfs-rdma.rst:21:wire bandwidth at minimal client CPU) under many workloads. The code passes
Documentation/admin-guide/nfs/nfs-rdma.rst-22-the full Connectathon test suite and operates over both Infiniband and iWARP
--
Documentation/admin-guide/nvme-multipath.rst=15=identifier into a single block device. Using multipath enhances the reliability
Documentation/admin-guide/nvme-multipath.rst:16:and stability of I/O access while improving bandwidth performance. When a user
Documentation/admin-guide/nvme-multipath.rst-17-sends I/O to this merged block device, the multipath mechanism selects one of
--
Documentation/admin-guide/nvme-multipath.rst=56=When to use the round-robin policy:
--
Documentation/admin-guide/nvme-multipath.rst-59- 2. Homogeneous Path Performance: Utilizes all paths efficiently when
Documentation/admin-guide/nvme-multipath.rst:60: performance characteristics (e.g., latency, bandwidth) are similar.
Documentation/admin-guide/nvme-multipath.rst-61-
--
Documentation/admin-guide/perf/alibaba_pmu.rst=53=By counting the READ, WRITE and RMW commands sent to the DDRC through the HIF
Documentation/admin-guide/perf/alibaba_pmu.rst:54:interface, we could calculate the bandwidth. Example usage of counting memory
Documentation/admin-guide/perf/alibaba_pmu.rst:55:data bandwidth::
Documentation/admin-guide/perf/alibaba_pmu.rst-56-
--
Documentation/admin-guide/perf/alibaba_pmu.rst-90-
Documentation/admin-guide/perf/alibaba_pmu.rst:91:Example usage of counting all memory read/write bandwidth by metric::
Documentation/admin-guide/perf/alibaba_pmu.rst-92-
Documentation/admin-guide/perf/alibaba_pmu.rst:93: perf stat -M ddr_read_bandwidth.all -- sleep 10
Documentation/admin-guide/perf/alibaba_pmu.rst:94: perf stat -M ddr_write_bandwidth.all -- sleep 10
Documentation/admin-guide/perf/alibaba_pmu.rst-95-
Documentation/admin-guide/perf/alibaba_pmu.rst:96:The average DRAM bandwidth can be calculated as follows:
Documentation/admin-guide/perf/alibaba_pmu.rst-97-
--
Documentation/admin-guide/perf/dwc_pcie_pmu.rst=76=Example usage of counting PCIe RX TLP data payload (Units of bytes)::
--
Documentation/admin-guide/perf/dwc_pcie_pmu.rst-79-
Documentation/admin-guide/perf/dwc_pcie_pmu.rst:80:The average RX/TX bandwidth can be calculated using the following formula:
Documentation/admin-guide/perf/dwc_pcie_pmu.rst-81-
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst=5=On Hip09, HiSilicon PCIe Performance Monitoring Unit (PMU) could monitor
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:6:bandwidth, latency, bus utilization and buffer occupancy data of PCIe.
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-7-
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst=35=Example usage of perf::
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-44-
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:45:The related events usually used to calculate the bandwidth, latency or others.
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-46-They need to start and end counting at the same time, therefore related events
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst=50=a) By event name, such as the latency events "xxx_latency, xxx_cnt" or
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:51: bandwidth events "xxx_flux, xxx_time".
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-52-b) By event type, such as "event=0xXXXX, event=0x1XXXX".
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst=61=Filter options
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-92-
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:93: "bdf" filter can only be used in bandwidth events, target Endpoint is
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:94: selected by configuring BDF to "bdf". Counter only counts the bandwidth of
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-95- message requested by target Endpoint.
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-107- "trig_len", and set the trigger mode by writing "trig_mode". This filter can
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:108: only be used in bandwidth events.
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-109-
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-121- threshold by writing "thr_len", and set the threshold mode by writing
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:122: "thr_mode". This filter can only be used in bandwidth events.
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-123-
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-133-
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:134: When counting bandwidth, the data can be composed of certain parts of TLP
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-135- packets. You can specify it through "len_mode":
--
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-141-
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:142: For example, "len_mode=2" means only counting the bandwidth of TLP headers
Documentation/admin-guide/perf/hisi-pcie-pmu.rst:143: and "len_mode=3" means the final bandwidth data is composed of both TLP
Documentation/admin-guide/perf/hisi-pcie-pmu.rst-144- headers and payloads. Default value if not specified is 2'b11.
--
Documentation/admin-guide/perf/hns3-pmu.rst=7=On Hip09, each SICL(Super I/O cluster) has one PMU device.
Documentation/admin-guide/perf/hns3-pmu.rst-8-
Documentation/admin-guide/perf/hns3-pmu.rst:9:HNS3 PMU supports collection of performance statistics such as bandwidth,
Documentation/admin-guide/perf/hns3-pmu.rst-10-latency, packet rate and interrupt rate.
--
Documentation/admin-guide/perf/meson-ddr-pmu.rst=4=Amlogic SoC DDR Bandwidth Performance Monitoring Unit (PMU)
--
Documentation/admin-guide/perf/meson-ddr-pmu.rst-6-
Documentation/admin-guide/perf/meson-ddr-pmu.rst:7:The Amlogic Meson G12 SoC contains a bandwidth monitor inside DRAM controller.
Documentation/admin-guide/perf/meson-ddr-pmu.rst-8-The monitor includes 4 channels. Each channel can count the request accessing
Documentation/admin-guide/perf/meson-ddr-pmu.rst=9=DRAM. The channel can count up to 3 AXI port simultaneously. It can be helpful
Documentation/admin-guide/perf/meson-ddr-pmu.rst:10:to show if the performance bottleneck is on DDR bandwidth.
Documentation/admin-guide/perf/meson-ddr-pmu.rst-11-
--
Documentation/admin-guide/perf/meson-ddr-pmu.rst=53=Examples:
Documentation/admin-guide/perf/meson-ddr-pmu.rst-54-
Documentation/admin-guide/perf/meson-ddr-pmu.rst:55: + Show the total DDR bandwidth per seconds:
Documentation/admin-guide/perf/meson-ddr-pmu.rst-56-
--
Documentation/admin-guide/perf/meson-ddr-pmu.rst-61-
Documentation/admin-guide/perf/meson-ddr-pmu.rst:62: + Show individual DDR bandwidth from CPU and GPU respectively, as well as
Documentation/admin-guide/perf/meson-ddr-pmu.rst-63- sum of them:
--
Documentation/admin-guide/perf/nvidia-tegra241-pmu.rst=5=The NVIDIA Tegra241 SoC includes various system PMUs to measure key performance
Documentation/admin-guide/perf/nvidia-tegra241-pmu.rst:6:metrics like memory bandwidth, latency, and utilization:
Documentation/admin-guide/perf/nvidia-tegra241-pmu.rst-7-
--
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst=5=The NVIDIA Tegra410 SoC includes various system PMUs to measure key performance
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst:6:metrics like memory bandwidth, latency, and utilization:
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-7-
--
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst=39=see /sys/bus/event_source/devices/nvidia_ucf_pmu_<socket-id>.
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-40-
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst:41:Some of the events available in this PMU can be used to measure bandwidth and
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-42-utilization:
--
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-53-
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst:54:The average bandwidth is calculated as::
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-55-
--
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst=126=see /sys/bus/event_source/devices/nvidia_pcie_pmu_<socket-id>_rc_<pcie-rc-id>.
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-127-
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst:128:The events in this PMU can be used to measure bandwidth, utilization, and
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-129-latency:
--
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-137-
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst:138:The average bandwidth is calculated as::
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-139-
--
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst=296=see /sys/bus/event_source/devices/nvidia_pcie_tgt_pmu_<socket-id>_rc_<pcie-rc-id>.
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-297-
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst:298:The events in this PMU can be used to measure bandwidth and utilization:
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-299-
--
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-305-
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst:306:The average bandwidth is calculated as::
Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst-307-
--
Documentation/admin-guide/quickly-build-trimmed-linux.rst=515=worth mentioning:
--
Documentation/admin-guide/quickly-build-trimmed-linux.rst-527- guide. Otherwise you will risk downloading nearly the entire git history,
Documentation/admin-guide/quickly-build-trimmed-linux.rst:528: which will consume quite a bit of time and bandwidth while also stressing the
Documentation/admin-guide/quickly-build-trimmed-linux.rst-529- servers.
--
Documentation/admin-guide/sysctl/kernel.rst=764=A rule of thumb is to set this to less than 1/10 of the PMEM node
Documentation/admin-guide/sysctl/kernel.rst:765:write bandwidth.
Documentation/admin-guide/sysctl/kernel.rst-766-
--
Documentation/admin-guide/sysctl/net.rst=173=queuing disciplines like Hierarchical Token Bucket or Deficit Round Robin
Documentation/admin-guide/sysctl/net.rst:174:which require setting up classes and bandwidths. Note that physical multiqueue
Documentation/admin-guide/sysctl/net.rst-175-interfaces still use mq as root qdisc, which in turn uses this default for its
--
Documentation/admin-guide/thunderbolt.rst=328=Possible values for ``<EVENT>`` are:
--
Documentation/admin-guide/thunderbolt.rst-333- changed
Documentation/admin-guide/thunderbolt.rst:334: There is a change in this tunnel. For example bandwidth allocation was
Documentation/admin-guide/thunderbolt.rst-335- changed.
--
Documentation/admin-guide/thunderbolt.rst-339-
Documentation/admin-guide/thunderbolt.rst:340: low bandwidth
Documentation/admin-guide/thunderbolt.rst:341: The tunnel is not getting optimal bandwidth.
Documentation/admin-guide/thunderbolt.rst-342-
Documentation/admin-guide/thunderbolt.rst:343: insufficient bandwidth
Documentation/admin-guide/thunderbolt.rst:344: There is not enough bandwidth for the current tunnel requirements.
Documentation/admin-guide/thunderbolt.rst-345-
--
Documentation/arch/arm64/acpi_object_usage.rst=215=HMAT Section 5.2.28 (signature == "HMAT")
--
Documentation/arch/arm64/acpi_object_usage.rst-219- This table describes the memory attributes, such as memory side cache
Documentation/arch/arm64/acpi_object_usage.rst:220: attributes and bandwidth and latency details, related to Memory Proximity
Documentation/arch/arm64/acpi_object_usage.rst-221- Domains. The OS uses this information to optimize the system memory
--
Documentation/arch/arm64/mpam.rst=38=The supported features are:
--
Documentation/arch/arm64/mpam.rst-45-
Documentation/arch/arm64/mpam.rst:46:* Memory bandwidth maximum controls (MBW_MAX) on or after the L3 cache.
Documentation/arch/arm64/mpam.rst:47: resctrl uses the L3 cache-id to identify where the memory bandwidth
Documentation/arch/arm64/mpam.rst-48- control is applied. For this reason the platform must have an L3 cache
--
Documentation/arch/arm64/mpam.rst-52- must match the topology of the L3 cache so that the cache-id's can be
Documentation/arch/arm64/mpam.rst:53: repainted. For example: Platforms with Memory bandwidth maximum controls
Documentation/arch/arm64/mpam.rst-54- on CPU-less NUMA nodes cannot expose the 'MB' schema to resctrl as these
Documentation/arch/arm64/mpam.rst:55: nodes do not have a corresponding L3 cache. If the memory bandwidth
Documentation/arch/arm64/mpam.rst-56- control is on the memory rather than the L3 then there must be a single
--
Documentation/arch/x86/amd_hsmp.rst=76=Following sysfs files are available at /sys/devices/platform/AMDI0097:0X/.
--
Documentation/arch/x86/amd_hsmp.rst-82-* protocol_version: HSMP interface version.
Documentation/arch/x86/amd_hsmp.rst:83:* ddr_max_bw: Theoretical maximum DDR bandwidth in GB/s.
Documentation/arch/x86/amd_hsmp.rst:84:* ddr_utilised_bw_input: Current utilized DDR bandwidth in GB/s.
Documentation/arch/x86/amd_hsmp.rst:85:* ddr_utilised_bw_perc_input(%): Percentage of current utilized DDR bandwidth.
Documentation/arch/x86/amd_hsmp.rst-86-* mclk_input: Memory clock in MHz.
--
Documentation/arch/x86/mds.rst=136=Mitigation points
--
Documentation/arch/x86/mds.rst-162- 3. It would take a large number of these precisely-timed NMIs to mount
Documentation/arch/x86/mds.rst:163: an actual attack. There's presumably not enough bandwidth.
Documentation/arch/x86/mds.rst-164- 4. The NMI in question occurs after a VERW, i.e. when user state is
--
Documentation/block/bfq-iosched.rst=7=controllers), BFQ's main features are:
--
Documentation/block/bfq-iosched.rst-11- players;
Documentation/block/bfq-iosched.rst:12:- BFQ distributes bandwidth, not just time, among processes or
Documentation/block/bfq-iosched.rst-13- groups (switching back to time distribution when needed to keep
--
Documentation/block/bfq-iosched.rst=124=instead, about the same throughput as the other schedulers.
Documentation/block/bfq-iosched.rst-125-
Documentation/block/bfq-iosched.rst:126:Strong fairness, bandwidth and delay guarantees
Documentation/block/bfq-iosched.rst-127-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--
Documentation/block/bfq-iosched.rst=130=among I/O-bound applications in proportion to their weights, with any
Documentation/block/bfq-iosched.rst:131:workload and regardless of the device parameters. From these bandwidth
Documentation/block/bfq-iosched.rst-132-guarantees, it is possible to compute a tight per-I/O-request delay
--
Documentation/block/bfq-iosched.rst=159=plus a lot of code, are borrowed from CFQ.
--
]
]
|
| 46/2 |
2026/05/17 19:08 |
llm |
expert |
0m
Model:
Tokens:
input: 104547
output: 66
thoughts: 1133
Thoughts: **Analysis of the Kernel Bug and its Exploitation**
Okay, let's break this down. First, regarding the assumption violation and potential denial-of-service, it seems pretty clear. The code warns if `sta->deflink.bandwidth` is greater than a configured channel width, which *could* indicate an issue. However, after careful review, it's apparent that `mac80211_hwsim` doesn't actually *use* that `bandwidth` value for anything beyond that warning message within `mac80211_hwsim_sta_rc_update`. So, despite the potential inconsistency, there are no practical consequences in terms of system crash, hangs, or resource leaks. Therefore, `DenialOfService` is definitely `false`.
Now, regarding exploitability, I had to double-check access through unprivileged processes. The reproducer utilizes `syz_genetlink_get_family_id` to obtain the `MAC80211_HWSIM` family ID and then attempts to register a socket using `HWSIM_CMD_REGISTER` through `syz_80211_inject_frame` which calls `hwsim_register_socket` in the end. This command requires `GENL_UNS_ADMIN_PERM`, which translates to needing `CAP_NET_ADMIN` within the user namespace.
The reproducer calls `hwsim_register_socket` which in turn calls `HWSIM_CMD_REGISTER`.
Here's the key: a process creating a new user namespace *and* network namespace has that `CAP_NET_ADMIN` by default in that new namespace. `mac80211_hwsim` specifically sets `.netnsok = true` in `hwsim_genl_family`, meaning it *can* be used from a network namespace. `GENL_UNS_ADMIN_PERM` allows usage if the process owns the network namespace and has `CAP_NET_ADMIN` in the user namespace.
So the conclusion is `UserNamespace: true`.
Then I examined further commands used by the reproducer: `NL80211_CMD_SET_INTERFACE` and `NL80211_CMD_JOIN_OCB`. `nl80211_small_ops` assigns `.flags = GENL_UNS_ADMIN_PERM` to these commands, and `nl80211_fam` sets `.netnsok = true`. That implies these commands are also accessible within a network namespace, therefore this also confirms `UserNamespace: true`.
I then considered autoloading of the `mac80211_hwsim` module if it's not already loaded. The netlink family `MAC80211_HWSIM` wouldn't exist without the module. However, `mac80211_hwsim` is typically an out-of-tree or testing module. But assuming the module can be loaded or autoloaded, I asked myself: can `MAC80211_HWSIM` be autoloaded? Netlink families can be autoloaded if they have an alias. The presence of `MODULE_ALIAS_GENL_FAMILY("MAC80211_HWSIM");` confirms it *can* be autoloaded. If so, an unprivileged process in a user namespace could trigger this via the request for the family ID. Thus, this also supports `UserNamespace: true`.
Finally, after confirming the analysis, the summary is as follows:
Exploitable: false
DenialOfService: false
Unprivileged: false
UserNamespace: true
VMGuestTrigger: false
VMHostTrigger: false
NetworkTrigger: false
RemoteTrigger: false
PeripheralTrigger: false
FilesystemTrigger: false
|
| 47/2 |
2026/05/17 19:08 |
tool |
set-results |
0m
Args: map[DenialOfService:false Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:true VMGuestTrigger:false VMHostTrigger:false]
Results: map[DenialOfService:false Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:true VMGuestTrigger:false VMHostTrigger:false]
|
| 48/2 |
2026/05/17 19:08 |
llm |
expert |
0m
Model:
Tokens:
input: 106635
output: 1033
thoughts: 13
Thoughts: Okay, here's the summary, rendered as your internal thought process:
**Finalizing the Response: Synthesis and Delivery**
The results are in, the analysis is complete, and the pieces have been connected. Now, it's time to craft the definitive response. No more prevarication, no more revisiting edge cases, just the clear, concise articulation of the findings. This isn't just about presenting data; it's about conveying understanding, illuminating the implications, and ensuring the user (who, of course, *understands* the nuances of this already) is able to grasp the significance of what's been uncovered. The rigor is there, the evidence is robust, and the explanation needs to be just as solid. So, I will write the final response now.
|
| 49/1 |
2026/05/17 19:08 |
action |
format-explanation |
0m
Results: map[Explanation:Based on the analysis of the bug report and the kernel source code, here is the
assessment of the bug's security impact:
**1. Exploitable: False**
The bug is a `WARN` in `mac80211_hwsim_sta_rc_update` that triggers when a
station's bandwidth (`bw`) is greater than the channel's configured bandwidth
(`confbw`). The `WARN` macro is used as a sanity check. In production builds,
this merely prints a warning message to the kernel log and continues execution.
The `bw` variable is not used for any subsequent logic or memory accesses within
the function, and `mac80211_hwsim` (being a software simulator) does not rely on
this bandwidth value for any critical operations. Therefore, this bug does not
lead to memory corruption, out-of-bounds accesses, or privilege escalation.
**2. Denial Of Service: False**
Since this is a `WARNING` and not a `BUG`, it does not halt the kernel in
production builds (assuming `panic_on_warn` is not set). The violation of the
assumption (station bandwidth > channel bandwidth) is not handled, but it also
has no adverse consequences because the `mac80211_hwsim` driver does not use the
bandwidth value for anything else. It does not cause a system crash, hang,
deadlock, or resource leak. The only consequence is a log message.
**3. Accessible From Unprivileged Processes: False**
The bug is triggered by injecting an 802.11 frame into a simulated radio
configured in OCB (Outside the Context of a BSS) mode. To configure an interface
in OCB mode, the process must send the `NL80211_CMD_JOIN_OCB` netlink command,
which requires the `GENL_UNS_ADMIN_PERM` flag (meaning it requires
`CAP_NET_ADMIN` in the user namespace). Furthermore, injecting frames into the
`mac80211_hwsim` simulator requires registering a socket via
`HWSIM_CMD_REGISTER`, which also requires `CAP_NET_ADMIN`. Thus, an unprivileged
process without namespace access cannot trigger this bug.
**4. Accessible From User Namespaces: True**
Both the `MAC80211_HWSIM` and `nl80211` netlink families have `.netnsok = true`,
meaning they are accessible within network namespaces. The required commands
(`HWSIM_CMD_REGISTER`, `NL80211_CMD_SET_INTERFACE`, `NL80211_CMD_JOIN_OCB`) use
the `GENL_UNS_ADMIN_PERM` flag, which allows execution if the process has
`CAP_NET_ADMIN` in the user namespace that owns the network namespace.
Therefore, an unprivileged user can create a new user/network namespace, gain
the necessary capabilities within it, and trigger the bug.
**5. VM Guest Trigger: False**
While `mac80211_hwsim` does have a virtio driver (`VIRTIO_ID_MAC80211_HWSIM`),
it is a testing tool and not a standard paravirtualized feature exposed to
typical KVM guests by default. The bug is triggered by user-space netlink
interactions within the OS where the simulator is running, not by standard
guest-to-host or host-to-guest VM exits.
**6. VM Host Trigger in The Confidential Computing Context: False**
Even if the host exposes the `mac80211_hwsim` virtio device to a guest, the bug
requires the guest to have already configured a wireless interface in OCB mode
(which is not a default configuration). The host cannot force the guest to
configure OCB mode, so it cannot reliably trigger the bug in the guest.
**7. Ethernet Network Trigger: False**
The bug involves processing 802.11 wireless frames, not Ethernet traffic.
Furthermore, it occurs within a software-simulated radio (`mac80211_hwsim`),
which does not receive traffic from real physical networks.
**8. Other Remote Trigger: False**
Because the bug is located in `mac80211_hwsim.c` (a software simulator for
testing), it cannot be triggered remotely over the air. Real wireless drivers
have their own station addition callbacks and do not use the simulator's code
path.
**9. Peripheral Trigger: False**
The bug is in a virtual/simulated driver, not a driver for a physical peripheral
device. Plugging in a malicious USB or other peripheral will not trigger this
code path.
**10. Malicious Filesystem Trigger: False**
The bug is entirely within the wireless networking subsystem and has no
interaction with filesystem mounting or parsing.]
|