diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 35273434aa562dd4c5128cced75d66b85981c494..6e7b7288cd201a051928c347ec1fae44b2571a03 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -687,6 +688,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session, return -EEXIST; } + err = -EINVAL; + if (!sk_is_tcp(sock->sk)) + goto free_socket; + err = iscsi_conn_bind(cls_session, cls_conn, is_leading); if (err) goto free_socket; diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index f9d8e8b1a4e8d244446d90d2457df59d32c40a47..91ba0da57d0c79b115c9fa99baf917ca5a493a18 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -521,4 +521,16 @@ static inline bool sk_psock_strp_enabled(struct sk_psock *psock) return false; return psock->parser.enabled; } + +static inline bool sk_is_tcp(const struct sock *sk) +{ + return sk->sk_type == SOCK_STREAM && + sk->sk_protocol == IPPROTO_TCP; +} + +static inline bool sk_is_udp(const struct sock *sk) +{ + return sk->sk_type == SOCK_DGRAM && + sk->sk_protocol == IPPROTO_UDP; +} #endif /* _LINUX_SKMSG_H */ diff --git a/net/core/filter.c b/net/core/filter.c index 62d09520a55d73037efebe0f7f30fc1a4241c7c0..fb84fd152fd720e79d8e712510809a9139ea410f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -10370,8 +10370,10 @@ BPF_CALL_3(bpf_sk_lookup_assign, struct bpf_sk_lookup_kern *, ctx, return -EINVAL; if (unlikely(sk && sk_is_refcounted(sk))) return -ESOCKTNOSUPPORT; /* reject non-RCU freed sockets */ - if (unlikely(sk && sk->sk_state == TCP_ESTABLISHED)) - return -ESOCKTNOSUPPORT; /* reject connected sockets */ + if (unlikely(sk && sk_is_tcp(sk) && sk->sk_state != TCP_LISTEN)) + return -ESOCKTNOSUPPORT; /* only accept TCP socket in LISTEN */ + if (unlikely(sk && sk_is_udp(sk) && sk->sk_state != TCP_CLOSE)) + return -ESOCKTNOSUPPORT; /* only accept UDP socket in CLOSE */ /* Check if socket is suitable for packet L3/L4 protocol */ if (sk && sk->sk_protocol != ctx->protocol) diff --git a/net/core/sock_map.c b/net/core/sock_map.c index c3c7f4469c80be09d71cfc763edd01bd0f5a08da..7f3788200cb88ee135f27dd5d35905d6ccf1311f 100644 --- a/net/core/sock_map.c +++ b/net/core/sock_map.c @@ -551,18 +551,6 @@ static bool sock_map_op_okay(const struct bpf_sock_ops_kern *ops) ops->op == BPF_SOCK_OPS_TCP_LISTEN_CB; } -static bool sk_is_tcp(const struct sock *sk) -{ - return sk->sk_type == SOCK_STREAM && - sk->sk_protocol == IPPROTO_TCP; -} - -static bool sk_is_udp(const struct sock *sk) -{ - return sk->sk_type == SOCK_DGRAM && - sk->sk_protocol == IPPROTO_UDP; -} - static bool sock_map_redirect_allowed(const struct sock *sk) { return sk_is_tcp(sk) && sk->sk_state != TCP_LISTEN;