diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 028513d3e2a2..e70796a1fe3e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3395,10 +3395,23 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname, } case TCP_ULP: { char name[TCP_ULP_NAME_MAX]; + struct sock *smc_sock; if (optlen < 1) return -EINVAL; + /* SMC sk_user_data may be treated as psock, + * which triggers a refcnt warning. + */ + rcu_read_lock(); + smc_sock = rcu_dereference_sk_user_data(sk); + if (level == SOL_TCP && smc_sock && + smc_sock->__sk_common.skc_family == AF_SMC) { + rcu_read_unlock(); + return -EOPNOTSUPP; + } + rcu_read_unlock(); + val = strncpy_from_sockptr(name, optval, min_t(long, TCP_ULP_NAME_MAX - 1, optlen));