mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
scm: add SO_PASSPIDFD and SCM_PIDFD
Implement SCM_PIDFD, a new type of CMSG type analogical to SCM_CREDENTIALS, but it contains pidfd instead of plain pid, which allows programmers not to care about PID reuse problem. We mask SO_PASSPIDFD feature if CONFIG_UNIX is not builtin because it depends on a pidfd_prepare() API which is not exported to the kernel modules. Idea comes from UAPI kernel group: https://uapi-group.org/kernel-features/ Big thanks to Christian Brauner and Lennart Poettering for productive discussions about this. Cc: "David S. Miller" <davem@davemloft.net> Cc: Eric Dumazet <edumazet@google.com> Cc: Jakub Kicinski <kuba@kernel.org> Cc: Paolo Abeni <pabeni@redhat.com> Cc: Leon Romanovsky <leon@kernel.org> Cc: David Ahern <dsahern@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Kees Cook <keescook@chromium.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Kuniyuki Iwashima <kuniyu@amazon.com> Cc: Lennart Poettering <mzxreary@0pointer.de> Cc: Luca Boccassi <bluca@debian.org> Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-arch@vger.kernel.org Tested-by: Luca Boccassi <bluca@debian.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
55d7c91406
commit
5e2ff6704a
@@ -1361,7 +1361,8 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (test_bit(SOCK_PASSCRED, &sock->flags) &&
|
||||
if ((test_bit(SOCK_PASSCRED, &sock->flags) ||
|
||||
test_bit(SOCK_PASSPIDFD, &sock->flags)) &&
|
||||
!unix_sk(sk)->addr) {
|
||||
err = unix_autobind(sk);
|
||||
if (err)
|
||||
@@ -1469,7 +1470,8 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr) {
|
||||
if ((test_bit(SOCK_PASSCRED, &sock->flags) ||
|
||||
test_bit(SOCK_PASSPIDFD, &sock->flags)) && !u->addr) {
|
||||
err = unix_autobind(sk);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -1670,6 +1672,8 @@ static void unix_sock_inherit_flags(const struct socket *old,
|
||||
{
|
||||
if (test_bit(SOCK_PASSCRED, &old->flags))
|
||||
set_bit(SOCK_PASSCRED, &new->flags);
|
||||
if (test_bit(SOCK_PASSPIDFD, &old->flags))
|
||||
set_bit(SOCK_PASSPIDFD, &new->flags);
|
||||
if (test_bit(SOCK_PASSSEC, &old->flags))
|
||||
set_bit(SOCK_PASSSEC, &new->flags);
|
||||
}
|
||||
@@ -1819,8 +1823,10 @@ static bool unix_passcred_enabled(const struct socket *sock,
|
||||
const struct sock *other)
|
||||
{
|
||||
return test_bit(SOCK_PASSCRED, &sock->flags) ||
|
||||
test_bit(SOCK_PASSPIDFD, &sock->flags) ||
|
||||
!other->sk_socket ||
|
||||
test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
|
||||
test_bit(SOCK_PASSCRED, &other->sk_socket->flags) ||
|
||||
test_bit(SOCK_PASSPIDFD, &other->sk_socket->flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1904,7 +1910,8 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr) {
|
||||
if ((test_bit(SOCK_PASSCRED, &sock->flags) ||
|
||||
test_bit(SOCK_PASSPIDFD, &sock->flags)) && !u->addr) {
|
||||
err = unix_autobind(sk);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -2718,7 +2725,8 @@ unlock:
|
||||
/* Never glue messages from different writers */
|
||||
if (!unix_skb_scm_eq(skb, &scm))
|
||||
break;
|
||||
} else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
|
||||
} else if (test_bit(SOCK_PASSCRED, &sock->flags) ||
|
||||
test_bit(SOCK_PASSPIDFD, &sock->flags)) {
|
||||
/* Copy credentials */
|
||||
scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
|
||||
unix_set_secdata(&scm, skb);
|
||||
|
Reference in New Issue
Block a user