From: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@xxxxxxxxxxxxx> Date: Sun, 9 Mar 2025 14:28:13 +0100 > Add SO_PEERCGROUPID which allows to get cgroup_id > for a socket. This looks useless for SOCK_DGRAM as the server can't have a peer for clients to send() or connect() (see unix_may_send()). Is there any reason to support only the connect()ed peer ? It seems the uAPI group expects to retrieve data per message as SCM_CGROUPID. > > We already have analogical interfaces to retrieve this > information: > - inet_diag: INET_DIAG_CGROUP_ID > - eBPF: bpf_sk_cgroup_id > > Having getsockopt() interface makes sense for many > applications, because using eBPF is not always an option, > while inet_diag has obvious complexety and performance drawbacks > if we only want to get this specific info for one specific socket. [...] > diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c > index 2b2c0036efc9..3455f38f033d 100644 > --- a/net/unix/af_unix.c > +++ b/net/unix/af_unix.c > @@ -901,6 +901,66 @@ static void unix_show_fdinfo(struct seq_file *m, struct socket *sock) > #define unix_show_fdinfo NULL > #endif > > +static int unix_getsockopt(struct socket *sock, int level, int optname, > + char __user *optval, int __user *optlen) > +{ > + struct sock *sk = sock->sk; > + > + union { > + int val; > + u64 val64; As Willem pointed out, simply use val64 only. > + } v; > + > + int lv = sizeof(int); > + int len; > + > + if (level != SOL_SOCKET) > + return -ENOPROTOOPT; > + > + if (get_user(len, optlen)) > + return -EFAULT; > + > + if (len < 0) > + return -EINVAL; > + > + memset(&v, 0, sizeof(v)); > + > + switch (optname) { > +#ifdef CONFIG_SOCK_CGROUP_DATA > + case SO_PEERCGROUPID: > + { > + struct sock *peer; > + u64 peer_cgroup_id = 0; Same remarks in patch 1, reverse xmas tree order, and no initialisation needed. > + > + lv = sizeof(u64); > + if (len < lv) > + return -EINVAL; > + > + peer = unix_peer_get(sk); > + if (!peer) > + return -ENODATA; > + > + peer_cgroup_id = cgroup_id(sock_cgroup_ptr(&peer->sk_cgrp_data)); > + sock_put(peer); > + > + v.val64 = peer_cgroup_id; > + break; > + } > +#endif > + default: > + return -ENOPROTOOPT; > + } > + > + if (len > lv) > + len = lv; > + if (copy_to_user(optval, &v, len)) > + return -EFAULT; > + if (put_user(len, optlen)) > + return -EFAULT; > + > + return 0; > +} > +