net: af_unix: enable custom setsockopt for all socket types

unix_setsockopt() and the SOCK_CUSTOM_SOCKOPT flag were only wired up
for SOCK_STREAM (introduced along with the stream-only SO_INQ).
Consequently custom AF_UNIX options are unreachable on SOCK_DGRAM and
SOCK_SEQPACKET: those setsockopt() calls bypass unix_setsockopt() and
fall through to the generic sock_setsockopt(), failing with
-ENOPROTOOPT.

Set SOCK_CUSTOM_SOCKOPT for every AF_UNIX socket type in unix_create(), and
also for accepted sockets in unix_accept() (reachable for stream and
seqpacket).

This is a prerequisite for making SO_RIGHTS_NOTRUNC settable on all AF_UNIX
socket types.

Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260813162818.149248-2-jkoolstra@xs4all.nl
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jori Koolstra
2026-08-13 12:28:15 -04:00
committed by Jakub Kicinski
parent 768af21721
commit de1c489b57

View File

@@ -950,7 +950,7 @@ static int unix_setsockopt(struct socket *sock, int level, int optname,
switch (optname) {
case SO_INQ:
if (sk->sk_type != SOCK_STREAM)
return -EINVAL;
return -ENOPROTOOPT;
if (val > 1 || val < 0)
return -EINVAL;
@@ -1006,6 +1006,7 @@ static const struct proto_ops unix_dgram_ops = {
#endif
.listen = sock_no_listen,
.shutdown = unix_shutdown,
.setsockopt = unix_setsockopt,
.sendmsg = unix_dgram_sendmsg,
.read_skb = unix_read_skb,
.recvmsg = unix_dgram_recvmsg,
@@ -1030,6 +1031,7 @@ static const struct proto_ops unix_seqpacket_ops = {
#endif
.listen = unix_listen,
.shutdown = unix_shutdown,
.setsockopt = unix_setsockopt,
.sendmsg = unix_seqpacket_sendmsg,
.recvmsg = unix_seqpacket_recvmsg,
.mmap = sock_no_mmap,
@@ -1143,9 +1145,10 @@ static int unix_create(struct net *net, struct socket *sock, int protocol,
if (protocol && protocol != PF_UNIX)
return -EPROTONOSUPPORT;
set_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags);
switch (sock->type) {
case SOCK_STREAM:
set_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags);
sock->ops = &unix_stream_ops;
break;
/*
@@ -1865,8 +1868,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock,
skb_free_datagram(sk, skb);
wake_up_interruptible(&unix_sk(sk)->peer_wait);
if (tsk->sk_type == SOCK_STREAM)
set_bit(SOCK_CUSTOM_SOCKOPT, &newsock->flags);
set_bit(SOCK_CUSTOM_SOCKOPT, &newsock->flags);
/* attach accepted sock to socket */
unix_state_lock(tsk);