Skip to content

tsi: don't call a NULL getsockopt in tsi_stream_getsockopt() - #153

Open
djbclark wants to merge 2 commits into
libkrun:mainfrom
djbclark:tsi-getsockopt-null
Open

djbclark wants to merge 2 commits into
libkrun:mainfrom
djbclark:tsi-getsockopt-null

Conversation

@djbclark

@djbclark djbclark commented Oct 17, 2026 •

Copy link
Copy Markdown

Closes #140.

tsi_stream_getsockopt() (also used for TSI datagram sockets) calls isocket->ops->getsockopt or vsocket->ops->getsockopt without a NULL check, but vsock_dgram_ops and the AF_UNIX proto_ops have no getsockopt. So a getsockopt() at a level other than SOL_SOCKET on a socket proxied through vsock oopses the guest. Minimal trigger, on 6.12.109:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM); s.connect(("1.1.1.1", 53)); s.send(b"x")
s.getsockopt(socket.IPPROTO_IP, socket.IP_TOS)

This guards both calls and returns -EOPNOTSUPP, which is what do_sock_getsockopt() returns for a socket without getsockopt, the fix proposed in #140. It also sets err for an unexpected status. The setsockopt paths already have this guard.

The change is folded into 0011-Transparent-Socket-Impersonation-implementation.patch, the way #107 did it; only af_tsi.c's hunk and the diffstat change. Checked: the full series applies to linux-6.12.109 with patch -p1 as the Makefile does, 0012 applies without offsets, and net/tsi/af_tsi.o builds for x86_64 with W=1 with no new warnings. I have not booted a guest with it; the same patch is proposed for SIPB's Hyades (https://forgejo.mit.edu/SIPB/hyades/pulls/12), where the repro can be run.

Prepared with an AI coding assistant; reviewed by me.

tsi_stream_getsockopt() calls isocket->ops->getsockopt or
vsocket->ops->getsockopt unconditionally, but vsock_dgram_ops and the
AF_UNIX proto_ops have no getsockopt. A getsockopt() at a level other
than SOL_SOCKET on a TSI datagram socket that was proxied through vsock
(for example IP_TOS on a connected UDP socket; reported with Chromium
and systemd-resolved) calls a NULL pointer and oopses the guest kernel.

Check the pointer and return -EOPNOTSUPP, which is what
do_sock_getsockopt() returns for a socket without getsockopt. Also set
err for an unexpected status instead of returning it uninitialized.

Closes: libkrun#140

Signed-off-by: Daniel JB Clark <djbclark@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The NULL-pointer fix only needs the getsockopt guards. Status is always
S_HYBRID/S_INET/S_VSOCK, and the original switch had no default; keep that.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TSI: getsockopt() on sockets proxied via vsock calls NULL vsock_dgram_ops.getsockopt

1 participant