]> git.ipfire.org Git - thirdparty/linux.git/commit
net/handshake: Pass negative errno through handshake_complete()
authorChuck Lever <chuck.lever@oracle.com>
Mon, 25 May 2026 16:51:17 +0000 (12:51 -0400)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 28 May 2026 11:35:31 +0000 (13:35 +0200)
commit6b22d433aa13f68e3cd9534ca9a5f4277bfa01c2
treee8e926a1c27f5312ef13eb3c86a60b44817c95ab
parent9015985b5eb1a90eb86caf5bce1dfcf1aa38f8ad
net/handshake: Pass negative errno through handshake_complete()

handshake_complete() declares status as unsigned int and
tls_handshake_done() negates that value (-status) before handing
it to the TLS consumer. Consumers match on negative errno
constants -- xs_tls_handshake_done() has

switch (status) {
case 0:
case -EACCES:
case -ETIMEDOUT:
lower_transport->xprt_err = status;
break;
default:
lower_transport->xprt_err = -EACCES;
}

so the API as designed expects callers to pass positive errno
values that the tlshd shim then negates.

Three internal callers in handshake_nl_accept_doit(), the
net-exit drain, and a kunit test follow kernel convention and
pass negative errnos -- -EIO, -ETIMEDOUT, -ETIMEDOUT. The
implicit conversion to unsigned int turns -ETIMEDOUT into
0xFFFFFF92; the subsequent -status in tls_handshake_done()
wraps back to 110, the consumer's switch falls through, and
the xprt reports -EACCES on what should be -ETIMEDOUT or -EIO.

Fix the API rather than the call sites. The natural kernel
convention is negative errno in, negative errno out. Change
handshake_complete() and hp_done to take int status, drop the
negation in tls_handshake_done(), and negate once in
handshake_nl_done_doit() where status arrives from the wire
as an unsigned netlink attribute. The three internal callers
were already correct under that convention and need no change.

At the same wire boundary, declare MAX_ERRNO as the netlink
policy upper bound for HANDSHAKE_A_DONE_STATUS. Attribute
validation rejects out-of-range values before
handshake_nl_done_doit() runs, and negating a bounded u32 there
stays within int range -- closing the UBSAN-visible signed-
integer overflow that an unconstrained u32 would invoke.

Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-3-66c616906ead@oracle.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/netlink/specs/handshake.yaml
net/handshake/genl.c
net/handshake/genl.h
net/handshake/handshake-test.c
net/handshake/handshake.h
net/handshake/netlink.c
net/handshake/request.c
net/handshake/tlshd.c