mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 01:52:03 +02:00
Merge branch 'net-psp-avoid-conflicts-with-skb-decrypted-and-sk_validate_xmit_skb'
Daniel Zahka says:
====================
net: psp: avoid conflicts with skb->decrypted and sk_validate_xmit_skb()
Sashiko's review of commit da630d1da2b1 ("netdevsim: psp: drop tx key
ops") [1] showed that there is a hazard between PSP and offloaded TLS,
where both can clobber what the other set in the sk_validate_xmit_skb
callback.
It was discussed further on the mailing list [2], and it was pointed out
that there are conflicts with PSP and TLS ULP both using the
skb->decrypted bit.
The simplest fix is to make psp and tls mutually exclusive. This series
goes a bit further and makes psp exclusive with all TCP ULPs. The PSP
implementation that we have is not designed to be used with any TCP ULP,
so don't allow a socket to have state for both.
I will send a subsequent series to net-next which will remove the
ability to perform the rx-assoc and tx-assoc psp netlink calls on
sockets that are not in the TCP_ESTABLISHED state. This will close the
remaining quirk that a sk_clone() on a listen socket with psp tx-assoc
state will leave a stale sk->sk_validate_xmit_skb call back on a new,
non-psp socket. I do not believe that change needs to be regarded as a
fix, because it only stands to add unecessary validation code in the tx
path.
[1]: https://sashiko.dev/#/patchset/20260903-psp-prep-v1-0-d47e9c4c375d%40gmail.com
[2]: https://lore.kernel.org/netdev/20260903-psp-prep-v1-0-d47e9c4c375d@gmail.com/
====================
Link: https://patch.msgid.link/20260915-psp-ktls-fix-v2-0-0eedc3b148ec@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
c9151088f1
|
|
@ -2312,6 +2312,8 @@ static inline void sk_gso_disable(struct sock *sk)
|
|||
sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
|
||||
}
|
||||
|
||||
bool sk_has_decrypt_user(const struct sock *sk);
|
||||
|
||||
static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
|
||||
struct iov_iter *from, char *to,
|
||||
int copy, int offset)
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@
|
|||
|
||||
#include <trace/events/sock.h>
|
||||
|
||||
#include <net/psp.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/busy_poll.h>
|
||||
#include <net/phonet/phonet.h>
|
||||
|
|
@ -2670,6 +2671,12 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(sk_setup_caps);
|
||||
|
||||
bool sk_has_decrypt_user(const struct sock *sk)
|
||||
{
|
||||
return psp_sk_assoc(sk) ||
|
||||
(sk_is_inet(sk) && inet_csk_has_ulp(sk)); /* for tls */
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple resource managers for sockets.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -136,6 +136,10 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
|
|||
if (icsk->icsk_ulp_ops)
|
||||
goto out_err;
|
||||
|
||||
err = -EINVAL;
|
||||
if (sk_has_decrypt_user(sk))
|
||||
goto out_err;
|
||||
|
||||
if (sk->sk_socket)
|
||||
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,10 @@ int psp_sock_assoc_set_rx(struct sock *sk, struct psp_assoc *pas,
|
|||
NL_SET_ERR_MSG(extack, "Socket already has PSP state");
|
||||
err = -EBUSY;
|
||||
goto exit_unlock;
|
||||
} else if (sk_has_decrypt_user(sk)) {
|
||||
NL_SET_ERR_MSG(extack, "Socket has incompatible state");
|
||||
err = -EINVAL;
|
||||
goto exit_unlock;
|
||||
}
|
||||
|
||||
refcount_inc(&pas->refcnt);
|
||||
|
|
|
|||
|
|
@ -21,5 +21,6 @@ CONFIG_NET_SCH_INGRESS=y
|
|||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_PPP=y
|
||||
CONFIG_PPPOE=y
|
||||
CONFIG_TLS=y
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_XDP_SOCKETS=y
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ from lib.py import NetNSEnter
|
|||
from lib.py import bkg, rand_port, wait_port_listen
|
||||
from lib.py import ip
|
||||
|
||||
TCP_ULP = 31
|
||||
|
||||
|
||||
def _get_outq(s):
|
||||
one = b'\0' * 4
|
||||
|
|
@ -333,6 +335,50 @@ def assoc_version_mismatch(cfg):
|
|||
ksft_eq(the_exception.nl_msg.error, -errno.EINVAL)
|
||||
|
||||
|
||||
def _require_tls_ulp():
|
||||
with socket.create_server(("localhost", 0)) as srv, \
|
||||
socket.create_connection(srv.getsockname()) as s:
|
||||
try:
|
||||
s.setsockopt(socket.SOL_TCP, TCP_ULP, b"tls")
|
||||
except OSError as exc:
|
||||
raise KsftSkipEx("kTLS not available") from exc
|
||||
|
||||
|
||||
def assoc_psp_ulp_exclusive(cfg):
|
||||
""" Test that a TCP ULP cannot be attached to a PSP socket """
|
||||
_init_psp_dev(cfg)
|
||||
_require_tls_ulp()
|
||||
|
||||
with _make_clr_conn(cfg) as s:
|
||||
try:
|
||||
cfg.pspnl.rx_assoc({"version": 0,
|
||||
"dev-id": cfg.psp_dev_id,
|
||||
"sock-fd": s.fileno()})
|
||||
with ksft_raises(OSError) as cm:
|
||||
s.setsockopt(socket.SOL_TCP, TCP_ULP, b"tls")
|
||||
ksft_eq(cm.exception.errno, errno.EINVAL)
|
||||
finally:
|
||||
_close_conn(cfg, s)
|
||||
|
||||
|
||||
def assoc_ulp_psp_exclusive(cfg):
|
||||
""" Test that a PSP assoc cannot be added to a socket with a TCP ULP """
|
||||
_init_psp_dev(cfg)
|
||||
_require_tls_ulp()
|
||||
|
||||
with _make_clr_conn(cfg) as s:
|
||||
try:
|
||||
s.setsockopt(socket.SOL_TCP, TCP_ULP, b"tls")
|
||||
with ksft_raises(NlError) as cm:
|
||||
cfg.pspnl.rx_assoc({"version": 0,
|
||||
"dev-id": cfg.psp_dev_id,
|
||||
"sock-fd": s.fileno()})
|
||||
ksft_eq(cm.exception.nl_msg.error, -errno.EINVAL)
|
||||
ksft_eq(cm.exception.nl_msg.extack['bad-attr'], ".sock-fd")
|
||||
finally:
|
||||
_close_conn(cfg, s)
|
||||
|
||||
|
||||
def assoc_twice(cfg):
|
||||
""" Test reusing Tx assoc for two sockets """
|
||||
_init_psp_dev(cfg)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user