ZeroHour

CVE-2026-81003

niche

Cross-device socket confusion in Linux kernel AF_IUCV/HiperSockets (s390x)

CVSS 3.1
8.1 high
EPSS
Published
()
Modified
AI analysis

The Linux kernel's AF_IUCV HiperSockets receive path (afiucv_hs_rcv()) matched incoming frames to sockets using only the four 8-byte plaintext name fields in the transport header, with no check that the frame arrived on the network device the socket was bound to. Any host on a shared HiperSockets (IQD) segment — or a local process with CAP_NET_RAW inside an unprivileged user/network namespace sending a raw ETH_P_AF_IUCV frame on its own loopback device — could deliver frames to sockets in init_net. This enables accept-queue exhaustion (denial of service), attacker-controlled peer identity in accepted child sockets, data injection into established connections, and fabricated replies that tear down live connections; additionally, classic z/VM IUCV sockets could receive HiperSockets frames, making the socket returned by accept() unusable (-ENODEV on first send). Only IBM Z (s390x) systems using AF_IUCV over HiperSockets or classic z/VM IUCV are affected, since the AF_IUCV address family exists only on that architecture. The upstream fix makes sockets reachable only from the exact IQD ingress device they were bound to; no public PoC or in-the-wild exploitation is known, and the issue is not on the CISA KEV list.

What to do: Apply a kernel build containing the fix (check your distribution's s390x kernel advisory) so that sockets are matched only against the ingress IQD device. As interim hardening, disable or restrict unprivileged user namespaces (e.g., user.max_user_namespaces=0) to close the local CAP_NET_RAW injection path, and treat every guest on a shared HiperSockets segment as a potential spoofer, since the protocol provides no per-connection authentication. Watch for tell-tale symptoms on IQD devices: accepted sockets that fail with -ENODEV on first send(), unexplained accept-queue growth, or established AF_IUCV connections being reset.

Affected
Linux kernel (net/iucv, AF_IUCV over HiperSockets / z/VM IUCV)
Estimated exposure
niche≈ hundreds to low thousands of s390x Linux guests at most — only IBM Z hosts actually using AF_IUCV sockets — AF_IUCV exists only on IBM Z (s390x), the global mainframe installed base is on the order of 10,000 systems, and only a small subset of Linux guests there use AF_IUCV rather than ordinary TCP/IP over HiperSockets.

Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.

Description

In the Linux kernel, the following vulnerability has been resolved: net/iucv: filter frames in afiucv_hs_rcv() by ingress device afiucv_hs_rcv() selects a socket from iucv_sk_list by matching four 8-byte name fields in the transport header alone. No check is made against the net_device the frame arrived on. This can cause a frame arriving on any netdev to be delivered to an AF_IUCV socket. Three problems follow. First, a frame arriving over HiperSockets can be delivered to a socket bound to the classic z/VM IUCV transport, which has iucv->hs_dev == NULL. iucv_sock_bind() takes the classic path whenever the requested userid matches iucv_userid, even on a guest that also has a HiperSockets device carrying the same identifier. The child socket created by afiucv_hs_callback_syn() for such a match inherits hs_dev = NULL and transport = AF_IUCV_TRANS_HIPER, so the first send() on it returns -ENODEV. The socket delivered to accept() is unusable. Second, a frame arriving on one netdev can be delivered to a socket bound to a different IQD device. Which can lead to - Accept-queue exhaustion (DoS) - Attacker-controlled peer identity in the child socket - Data injection into existing sockets - Fabric noise on the IQD fabric, where bogus replies are sent - killing established connections Third, all AF_IUCV sockets live in init_net, as iucv_sock_alloc() calls sk_alloc(&init_net, ...). But even frames arriving on netdev devices in a namespace can be delivered to an IUCV socket. So a process in an unprivileged user and network namespace holding only the CAP_NET_RAW capability valid within that namespace can send a raw ETH_P_AF_IUCV frame on its own lo device and have it matched against init_net sockets. Fix all three by skipping any socket whose hs_dev does not match the ingress device. A classic z/VM IUCV socket has hs_dev == NULL; the ingress dev is never NULL, so classic sockets are skipped automatically. An unbound HIPER socket also has hs_dev == NULL and is skipped. A bound HIPER socket is only reachable from the exact IQD device it was bound to. Because hs_dev is always a device in init_net (iucv_sock_bind() scans for_each_netdev_rcu(&init_net, ...) exclusively), a frame whose ingress device belongs to another namespace never matches any socket. Note that AF_IUCV over HiperSockets provides no per-connection authentication: no sequence numbers, no TLS, no nonce. The four name fields identifying a connection are exchanged in plaintext on the shared HiperSockets segment (VCHID). Any host on the same HiperSockets segment could spoof any frame type against an existing connection. That is a protocol-level property unchanged by this patch. The fix reduces the attack surface to peers present on the same HiperSockets segment.

Vector
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H

In the news

No ingested article mentions this CVE yet.