From patchwork Tue Apr 11 10:42:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 81873 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2475502vqo; Tue, 11 Apr 2023 03:47:31 -0700 (PDT) X-Google-Smtp-Source: AKy350Z9wWK67PZBzwO8kX8fNIfxnt+XgdT+LUVASBc1OM2lZ52jAUM2Xdj17rQtMInu0bv9qWr2 X-Received: by 2002:a17:902:f985:b0:1a5:1438:9bcd with SMTP id ky5-20020a170902f98500b001a514389bcdmr13289818plb.35.1681210051043; Tue, 11 Apr 2023 03:47:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681210051; cv=none; d=google.com; s=arc-20160816; b=1C4/bZvDON0pZ/KpOxa0cX5RST8QSNUYXgiRMb+V3c/1QXNX76rWQaeGNPsFiKznJ0 KK8oTlETHZSBVA4MJE/v6/Z9e8nmC3dkX/D6rKLtb8Zmqgt7JZmXux9J297I1a37tnuk EouxBfP+QKIM5z9isCLpGyVmgYmKilhQiATwMLr5g9gEMq+V7APzAXimZuIPHrxRGQY+ 3GU0D4zUHFI9CN4pxF+DFkzv0z0NVpwFatzC23R9Wes9q8bW6HMwFgcuQU9iFtF3BCrH +IIJH6GJcGJDbGTxwy/w9HjE5KzsZLLSIkgQp+BQbEc2/nPbDXH3p5yQEfP/R8jsYclG dRmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=a+6gxbvn4hYwO5enGV6t44vz4Ixp1BNaXg7ewl6XAKs=; b=dYk2Z532XEyIL5z4YB7N/1kvq5N3yLsF3Pc6FwhzWgYDlpFHbjw2rWPq6Jeutu3p3I EZzJqaqJ40CeiRnw8Q5hsggYO1wJ9elXACPqDCROA6CClpeGY+z7NMiZm0ltkIW/Tzl7 uaxt7naubreAKx49q3Ps0BN77tsALtT3wyv2vYhG89cqZMLpCG3CBbCM0BN6agQmWBAF VM9sFu2GCyY78/d1eeSNOfb58TPR5XHkEKKX0pwzPgRYvpl2mitPCdq39rO58cNeDvag 3YCnSzr5lZxA4tOSiSjUtqc84UktrSv2doRykEznCIYDfPn5wjtDu5WKwz2x2XTp3LE2 kJXw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=etClHLva; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h3-20020a63e143000000b0050f57f9b330si13161678pgk.266.2023.04.11.03.47.19; Tue, 11 Apr 2023 03:47:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=etClHLva; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229863AbjDKKne (ORCPT + 99 others); Tue, 11 Apr 2023 06:43:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229861AbjDKKn1 (ORCPT ); Tue, 11 Apr 2023 06:43:27 -0400 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F69230F5 for ; Tue, 11 Apr 2023 03:43:22 -0700 (PDT) Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id DA6D53F244 for ; Tue, 11 Apr 2023 10:43:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1681209800; bh=a+6gxbvn4hYwO5enGV6t44vz4Ixp1BNaXg7ewl6XAKs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=etClHLvaMSvWEG3YGfzCx9n/Y5As7kOUXYqQM2/azBQTR2sPDf0jt2pJuvqiCHelQ hRoc4N3yUnb68JEi1DoAAxhoimj2XPsAhbHmRnua0o2M1gme7nESODcznW1cAn760F Dd2BOD4dSF5cz2m9kYSFdsL4/nBcobjv6Z/dQ/deg0JE8+ha6mvd2VTcL0VtOK4nMp LrJl4LiR22bpq0Ix2FZrUX5oAq2JvUTpbDqG8Stxufl1twW7Y6GxsLOJ76WF5FVazP dSRx1UUFo2WYmBLtHDMfOwpqG0wahniby6HuiuM4kp4kOl4cwO7YTI2u19Cj8F2RUS kpKely6rQgpig== Received: by mail-ej1-f72.google.com with SMTP id vt6-20020a170907a60600b009217998c8e3so2397463ejc.14 for ; Tue, 11 Apr 2023 03:43:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681209800; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=a+6gxbvn4hYwO5enGV6t44vz4Ixp1BNaXg7ewl6XAKs=; b=j1ppURx/CkWcqawOMhOnhN+DHRfgTaDbdH0Ox7dhFGWqHyUMTRcKF93bUbZ5j6298w UOVyVzt31Z4g04+Sc+oyUQw9R8sw8d7Iolf0bNL+5wq8GAg5xBOUezZImfAsEi38CTN8 I4r7AjgrghJ3/ZiEFy9idIqFKi5h8c0oMVf/+QhBRu0o0eOyBj9uNZAebyX6FQIlV+AW IiOzk+881zaUhXK26caQeing5H8/fiHmrfmEsatpSVQbZElorK6Yy/qAXJeLPfqQ/eSO cpvD3BJs/6IZLcP2XEN+2iuaLtL2XVD15yd3e5okE5DwwaZMiWbmqqMr4vq4bDY3xc1R dWOA== X-Gm-Message-State: AAQBX9fjLsFbHDI3DbqIviRbmqa+dD0OtJhgNP35koRLYgCDnBJVX9AG Qmec6doyxHw2dBEgt0D8n3sOB/tSjD6P7IJ5gbeKrOZl2wGZ9Ebyniupxa2zcNuFbNfoWqxPPby /xsqHIWeaLOSbsSmj1U501ZuAfk9ud2IHd+Oq03B4oQ== X-Received: by 2002:a17:906:a859:b0:94c:784f:7569 with SMTP id dx25-20020a170906a85900b0094c784f7569mr4265431ejb.30.1681209800371; Tue, 11 Apr 2023 03:43:20 -0700 (PDT) X-Received: by 2002:a17:906:a859:b0:94c:784f:7569 with SMTP id dx25-20020a170906a85900b0094c784f7569mr4265406ejb.30.1681209799970; Tue, 11 Apr 2023 03:43:19 -0700 (PDT) Received: from amikhalitsyn.. ([95.91.208.118]) by smtp.gmail.com with ESMTPSA id ne7-20020a1709077b8700b00948c320fcfdsm5921805ejc.202.2023.04.11.03.43.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Apr 2023 03:43:19 -0700 (PDT) From: Alexander Mikhalitsyn To: davem@davemloft.net Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Alexander Mikhalitsyn , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Leon Romanovsky , David Ahern , Arnd Bergmann , Kees Cook , Christian Brauner , Kuniyuki Iwashima , Lennart Poettering , Luca Boccassi , linux-arch@vger.kernel.org Subject: [PATCH net-next v3 1/4] scm: add SO_PASSPIDFD and SCM_PIDFD Date: Tue, 11 Apr 2023 12:42:28 +0200 Message-Id: <20230411104231.160837-2-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230411104231.160837-1-aleksandr.mikhalitsyn@canonical.com> References: <20230411104231.160837-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.5 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762876510062841660?= X-GMAIL-MSGID: =?utf-8?q?1762876510062841660?= 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. 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" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Leon Romanovsky Cc: David Ahern Cc: Arnd Bergmann Cc: Kees Cook Cc: Christian Brauner Cc: Kuniyuki Iwashima Cc: Lennart Poettering Cc: Luca Boccassi Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-arch@vger.kernel.org Tested-by: Luca Boccassi Reviewed-by: Kuniyuki Iwashima Signed-off-by: Alexander Mikhalitsyn --- v2: According to review comments from Kuniyuki Iwashima and Christian Brauner: - use pidfd_create(..) retval as a result - whitespace change --- arch/alpha/include/uapi/asm/socket.h | 2 ++ arch/mips/include/uapi/asm/socket.h | 2 ++ arch/parisc/include/uapi/asm/socket.h | 2 ++ arch/sparc/include/uapi/asm/socket.h | 2 ++ include/linux/net.h | 1 + include/linux/socket.h | 1 + include/net/scm.h | 14 ++++++++++++-- include/uapi/asm-generic/socket.h | 2 ++ net/core/sock.c | 11 +++++++++++ net/mptcp/sockopt.c | 1 + net/unix/af_unix.c | 18 +++++++++++++----- tools/include/uapi/asm-generic/socket.h | 2 ++ 12 files changed, 51 insertions(+), 7 deletions(-) diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 739891b94136..ff310613ae64 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -137,6 +137,8 @@ #define SO_RCVMARK 75 +#define SO_PASSPIDFD 76 + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 18f3d95ecfec..762dcb80e4ec 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -148,6 +148,8 @@ #define SO_RCVMARK 75 +#define SO_PASSPIDFD 76 + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index f486d3dfb6bb..df16a3e16d64 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -129,6 +129,8 @@ #define SO_RCVMARK 0x4049 +#define SO_PASSPIDFD 0x404A + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 2fda57a3ea86..6e2847804fea 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -130,6 +130,8 @@ #define SO_RCVMARK 0x0054 +#define SO_PASSPIDFD 0x0055 + #if !defined(__KERNEL__) diff --git a/include/linux/net.h b/include/linux/net.h index b73ad8e3c212..c234dfbe7a30 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -43,6 +43,7 @@ struct net; #define SOCK_PASSSEC 4 #define SOCK_SUPPORT_ZC 5 #define SOCK_CUSTOM_SOCKOPT 6 +#define SOCK_PASSPIDFD 7 #ifndef ARCH_HAS_SOCKET_TYPES /** diff --git a/include/linux/socket.h b/include/linux/socket.h index 13c3a237b9c9..6bf90f251910 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -177,6 +177,7 @@ static inline size_t msg_data_left(struct msghdr *msg) #define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */ #define SCM_CREDENTIALS 0x02 /* rw: struct ucred */ #define SCM_SECURITY 0x03 /* rw: security label */ +#define SCM_PIDFD 0x04 /* ro: pidfd (int) */ struct ucred { __u32 pid; diff --git a/include/net/scm.h b/include/net/scm.h index 585adc1346bd..0c717ae9c8db 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -124,8 +124,9 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm, int flags) { if (!msg->msg_control) { - if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp || - scm_has_secdata(sock)) + if (test_bit(SOCK_PASSCRED, &sock->flags) || + test_bit(SOCK_PASSPIDFD, &sock->flags) || + scm->fp || scm_has_secdata(sock)) msg->msg_flags |= MSG_CTRUNC; scm_destroy(scm); return; @@ -141,6 +142,15 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds); } + if (test_bit(SOCK_PASSPIDFD, &sock->flags)) { + int pidfd; + + WARN_ON_ONCE(!scm->pid); + pidfd = pidfd_create(scm->pid, 0); + + put_cmsg(msg, SOL_SOCKET, SCM_PIDFD, sizeof(int), &pidfd); + } + scm_destroy_cred(scm); scm_passec(sock, msg, scm); diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index 638230899e98..b76169fdb80b 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -132,6 +132,8 @@ #define SO_RCVMARK 75 +#define SO_PASSPIDFD 76 + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__)) diff --git a/net/core/sock.c b/net/core/sock.c index c25888795390..3f974246ba3e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1246,6 +1246,13 @@ int sk_setsockopt(struct sock *sk, int level, int optname, clear_bit(SOCK_PASSCRED, &sock->flags); break; + case SO_PASSPIDFD: + if (valbool) + set_bit(SOCK_PASSPIDFD, &sock->flags); + else + clear_bit(SOCK_PASSPIDFD, &sock->flags); + break; + case SO_TIMESTAMP_OLD: case SO_TIMESTAMP_NEW: case SO_TIMESTAMPNS_OLD: @@ -1737,6 +1744,10 @@ int sk_getsockopt(struct sock *sk, int level, int optname, v.val = !!test_bit(SOCK_PASSCRED, &sock->flags); break; + case SO_PASSPIDFD: + v.val = !!test_bit(SOCK_PASSPIDFD, &sock->flags); + break; + case SO_PEERCRED: { struct ucred peercred; diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index b655cebda0f3..67be0558862f 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -355,6 +355,7 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname, case SO_BROADCAST: case SO_BSDCOMPAT: case SO_PASSCRED: + case SO_PASSPIDFD: case SO_PASSSEC: case SO_RXQ_OVFL: case SO_WIFI_STATUS: diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index fb31e8a4409e..6d5dff4dfe83 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -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); } /* @@ -1922,7 +1928,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; @@ -2824,7 +2831,8 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, /* 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); diff --git a/tools/include/uapi/asm-generic/socket.h b/tools/include/uapi/asm-generic/socket.h index 8756df13be50..fbbc4bf53ee3 100644 --- a/tools/include/uapi/asm-generic/socket.h +++ b/tools/include/uapi/asm-generic/socket.h @@ -121,6 +121,8 @@ #define SO_RCVMARK 75 +#define SO_PASSPIDFD 76 + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__)) From patchwork Tue Apr 11 10:42:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 81879 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2480757vqo; Tue, 11 Apr 2023 04:00:10 -0700 (PDT) X-Google-Smtp-Source: AKy350bT7PbofFCpwyeuennlMVtf7TgzbLokOEaPhGs5LHR2smP9SW274Thk6pktHk4ipvkejK0w X-Received: by 2002:a17:903:2312:b0:1a6:39f7:eb2b with SMTP id d18-20020a170903231200b001a639f7eb2bmr3213041plh.2.1681210810544; Tue, 11 Apr 2023 04:00:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681210810; cv=none; d=google.com; s=arc-20160816; b=m7Phrb2DW2Uz/vb5pRird2fUvuhtJdS09vxx5CD+bhoc1Z4p2euC8TLv/BnDzSv/2F ymlZNri1/hIw/itrfIQ61sXyU8/CzO8mctjey6iX7eoWdFbHeeK38kqWkk8tu2+5Nl09 ctjI/R506WWNk5JwOwhB8Vy5QeuPm+5j68yfWzpxRzEscRq3BE4JXfUwRHdiQZWc4DBQ 8BmdpsS0yVrsNvCIFLfZ6uNn8TU5lS9ySZjm8RVn5203UYTtMDY/nb6/0a6RDQhO6Vgr KqEQtYKWdFjhmHKiw7XBbxoBbCGTOOK5zhyD5a6loQfDUDHgR7F4fNJB1RUCBQ8u6H0B bw8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=pU+XkxxaqxIltFz6HAiJgXotXtTecmR/abIbMqTWsWw=; b=St316h3r194NbQUgS9ICzHvfSRFsnw49Rx9L2aR3WNjbRZfejCH3bsDuFG2LY1lQEI ZBohRIhjrbn5n6ULU4+GvkMicfsA3cv3HFt1hzgGhOeKWUJFdpRk0aXz57gNEd8r5tTM mHkMv0EcDTuJvDDjbF9eRjXu6fW0jeLI/3wzjg4r73J3UGYcIB852RL/1bA2hMVL0Msp Mbh0w5w+vbJK6JL1bigWCajhz02lWu9iNuZ+DOwE9MtucZWMmrrdHWPfuYDatx8VcuV7 S/jpTnPlucbTKfLGnJAxy+PM57YkoxGkr3GU4bFdnalqTG/kbIonIwpWxoDURq+q9vGv YBTg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=Z06CA+Jc; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id lh8-20020a170903290800b001a642057764si4144042plb.180.2023.04.11.03.59.58; Tue, 11 Apr 2023 04:00:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=Z06CA+Jc; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229862AbjDKKnx (ORCPT + 99 others); Tue, 11 Apr 2023 06:43:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34634 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229532AbjDKKnp (ORCPT ); Tue, 11 Apr 2023 06:43:45 -0400 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B4CF3C1F for ; Tue, 11 Apr 2023 03:43:32 -0700 (PDT) Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id CBCBF3F237 for ; Tue, 11 Apr 2023 10:43:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1681209810; bh=pU+XkxxaqxIltFz6HAiJgXotXtTecmR/abIbMqTWsWw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Z06CA+JcDdJSFA9PnH61/Q3e0p+z11skMn3k+JedjsCMAnWO3NCgcJES26N4PNFfs 3S5I/ZLknwsf3zB991NJIy0DPB9P7ps9Qyfr/N5hpVr4WAdf+aRhvQFcus2d2rChn/ lk446tSYDUX6ooVqg9Nf0fW6Ec8X42j0wTauiriComSpNn4RRjoNZw0D5ISr2oED/9 fUQgYjYw+YE77RvMSw+SpBnfZ4224/8gyPDLdYI0sgusM3RQlhYPH2okArpyL1pLvu P4GRnceeOPPH7X/JtXEZIN13S7xdLyFEsu1RDb8WowET8yEARhQLp+BTQ0tB4D0r7m fdrp7mYQiI2zg== Received: by mail-ej1-f72.google.com with SMTP id b3-20020a170906038300b009489cf242c8so4397490eja.4 for ; Tue, 11 Apr 2023 03:43:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681209810; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pU+XkxxaqxIltFz6HAiJgXotXtTecmR/abIbMqTWsWw=; b=Rs5cX7BjPuM4w9WZt3o3gIfbDFAzaCqpmAkjX9jDSOkAmhvS2g/QovSfZcUUEwYuRC Coe4siqVkDojdyO4W/Irt5soZdVlurXwTsX6ZZ8FJCbvdI3ymJNrRcYvkcIM8AVQJ13E 3u8q/WSNwjWBnwKdrTeGk367Afv9q6TuDQUxwxIn3iQTvkSRUTOSvgVLjtM2zCqDNz52 QEuPmjI1BF+6QYlkPHKvKXNzXkLsD6uNwff+mzOwTkv2lQPC6ncxTrtO+O7yBuaBN03l 5gzw3f85VaWMHGXbSWu2QpNvDL38SoqRCQvUjMMykYEVIedgBzcNgEA4iYfPLp+1gEDj QReQ== X-Gm-Message-State: AAQBX9cUKhdp5t5VK7q+CkvVNaP5PJV+98FQHwq4o+qCHVz8Bs4N3T5P hh9JrdefL55A00Ter9c6ckFvFVyMKyv7wXzLY4OcQcc2Gf9yTQ175ms48E0Guw4euMxvNeQAkRe B/QLK9XY6NbCl6t6HTW3hios/wl4tyo7W02JvPlPSbw== X-Received: by 2002:a17:907:6a12:b0:94a:474a:4dd7 with SMTP id rf18-20020a1709076a1200b0094a474a4dd7mr7376313ejc.60.1681209810561; Tue, 11 Apr 2023 03:43:30 -0700 (PDT) X-Received: by 2002:a17:907:6a12:b0:94a:474a:4dd7 with SMTP id rf18-20020a1709076a1200b0094a474a4dd7mr7376308ejc.60.1681209810274; Tue, 11 Apr 2023 03:43:30 -0700 (PDT) Received: from amikhalitsyn.. ([95.91.208.118]) by smtp.gmail.com with ESMTPSA id ne7-20020a1709077b8700b00948c320fcfdsm5921805ejc.202.2023.04.11.03.43.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Apr 2023 03:43:29 -0700 (PDT) From: Alexander Mikhalitsyn To: davem@davemloft.net Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Alexander Mikhalitsyn , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Leon Romanovsky , David Ahern , Arnd Bergmann , Kees Cook , Christian Brauner , Kuniyuki Iwashima , Lennart Poettering , linux-arch@vger.kernel.org, Daniel Borkmann Subject: [PATCH net-next v3 2/4] net: socket: add sockopts blacklist for BPF cgroup hook Date: Tue, 11 Apr 2023 12:42:29 +0200 Message-Id: <20230411104231.160837-3-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230411104231.160837-1-aleksandr.mikhalitsyn@canonical.com> References: <20230411104231.160837-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.5 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762877307215632294?= X-GMAIL-MSGID: =?utf-8?q?1762877307215632294?= During work on SO_PEERPIDFD, it was discovered (thanks to Christian), that bpf cgroup hook can cause FD leaks when used with sockopts which install FDs into the process fdtable. After some offlist discussion it was proposed to add a blacklist of socket options those can cause troubles when BPF cgroup hook is enabled. Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Leon Romanovsky Cc: David Ahern Cc: Arnd Bergmann Cc: Kees Cook Cc: Christian Brauner Cc: Kuniyuki Iwashima Cc: Lennart Poettering Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-arch@vger.kernel.org Suggested-by: Daniel Borkmann Suggested-by: Christian Brauner Signed-off-by: Alexander Mikhalitsyn Acked-by: Christian Brauner --- net/socket.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/net/socket.c b/net/socket.c index 73e493da4589..9c1ef11de23f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -108,6 +108,8 @@ #include #include +#include + #ifdef CONFIG_NET_RX_BUSY_POLL unsigned int sysctl_net_busy_read __read_mostly; unsigned int sysctl_net_busy_poll __read_mostly; @@ -2227,6 +2229,36 @@ static bool sock_use_custom_sol_socket(const struct socket *sock) return test_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags); } +#ifdef CONFIG_CGROUP_BPF +static bool sockopt_installs_fd(int level, int optname) +{ + /* + * These options do fd_install(), and if BPF_CGROUP_RUN_PROG_GETSOCKOPT + * hook returns an error after success of the original handler + * sctp_getsockopt(...), userspace will receive an error from getsockopt + * syscall and will be not aware that fd was successfully installed into fdtable. + * + * Let's prevent bpf cgroup hook from running on them. + */ + if (level == SOL_SCTP) { + switch (optname) { + case SCTP_SOCKOPT_PEELOFF: + case SCTP_SOCKOPT_PEELOFF_FLAGS: + return true; + default: + return false; + } + } + + return false; +} +#else /* CONFIG_CGROUP_BPF */ +static inline bool sockopt_installs_fd(int level, int optname) +{ + return false; +} +#endif /* CONFIG_CGROUP_BPF */ + /* * Set a socket option. Because we don't know the option lengths we have * to pass the user mode parameter for the protocols to sort out. @@ -2250,7 +2282,7 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval, if (err) goto out_put; - if (!in_compat_syscall()) + if (!in_compat_syscall() && !sockopt_installs_fd(level, optname)) err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname, user_optval, &optlen, &kernel_optval); @@ -2304,7 +2336,7 @@ int __sys_getsockopt(int fd, int level, int optname, char __user *optval, if (err) goto out_put; - if (!in_compat_syscall()) + if (!in_compat_syscall() && !sockopt_installs_fd(level, optname)) max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen); if (level == SOL_SOCKET) @@ -2315,7 +2347,7 @@ int __sys_getsockopt(int fd, int level, int optname, char __user *optval, err = sock->ops->getsockopt(sock, level, optname, optval, optlen); - if (!in_compat_syscall()) + if (!in_compat_syscall() && !sockopt_installs_fd(level, optname)) err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname, optval, optlen, max_optlen, err); From patchwork Tue Apr 11 10:42:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 81876 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2479253vqo; Tue, 11 Apr 2023 03:56:35 -0700 (PDT) X-Google-Smtp-Source: AKy350YY1/EZOqQBYWOh4DkAqAoTHRFLC5+bmGpUIEzCwcfU1b4u0Trn3ITDwb7TBksXVaulXLxn X-Received: by 2002:a17:90b:1b05:b0:239:ea16:5b13 with SMTP id nu5-20020a17090b1b0500b00239ea165b13mr18549507pjb.14.1681210595099; Tue, 11 Apr 2023 03:56:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681210595; cv=none; d=google.com; s=arc-20160816; b=uUWuxEC71hr/sjsz3Lmwk+WiPlVVbbMDeoTtbIEdKWigaWwTpPXAUMz7i7eAxuTHr/ ksd0yTuROZdPpk3iD/kNG6x5BCL98620fSayVqOeCYGX+9XVW1fT/ZqJPOBI0HOKLhzp cjAxPWEw3Rsd30lLUjKVvsNRI4c2OwgcpcyVXKd0zC3OYGt9EBirK40Pp832jpzAwuVs J3FKrO9virYVgcUSLWUtKipWZ2dMggyojMTwXt52+DabLP58I55qQc3w2bpV5s5RSoh5 QwAwCaqpEuNK5vycqrUB8rWjFwgm9ApJGqTRXu429/otxIuYBD/J7zc8v0ryLK+SRiOq 48jQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=pRf5xzGSUbwksyzKh9EFSxutG5TUV/lwNKq2bZMboXc=; b=H1lrzqX7uuEvw/ciN2IXa2Au2Xy2aIFiEb6PRiYB4efrGjmQ5R97oNGH2HXaj83KzI D719N3PAXcBTrDXSi0A+Ztbeqr2gLYjEfIoKsWxNs8WRe8ukA2gnhpHMHhok2P/NYL/B D31dHFAX7pVdt9WxslOPKhTkEtrYBwoM1uQRBNXfzg7y753zzFqOAsJmfLGHZJmk4Q7t Mxgv02u5vmkrHJwO5hkvIZY5u5gu057vfuFlHs/Uj4zC/Uowvl6mJMCEh3NCqkHHd+/u LEMUs8Vz+mbK0mfrS45x2/Uv75EgPi3az/rd9+nxwAaXhq8ZGiLJFF+OJEzUm9MX2oI6 IyFw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=oQ5CAUA5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id oa18-20020a17090b1bd200b0023f1166af5dsi13512136pjb.170.2023.04.11.03.56.22; Tue, 11 Apr 2023 03:56:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=oQ5CAUA5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229924AbjDKKoP (ORCPT + 99 others); Tue, 11 Apr 2023 06:44:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229910AbjDKKn7 (ORCPT ); Tue, 11 Apr 2023 06:43:59 -0400 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A624D40E8 for ; Tue, 11 Apr 2023 03:43:45 -0700 (PDT) Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 55EF13F23B for ; Tue, 11 Apr 2023 10:43:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1681209823; bh=pRf5xzGSUbwksyzKh9EFSxutG5TUV/lwNKq2bZMboXc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oQ5CAUA5XLp4H0AMWn/3n9/+CjrnqZRPgOOcoZcxlOP4dgRPrvV+suah8Aj+Um3Pc 01XalS4nfgYk9smqPEZZabrkzyiupaD20wJ8lacaoLtIMukbHWyx1E/X2PhphxCBOB zl1hkDcfohGfXiCLkU8vq4+z3V2W8J75fVuB+/Gb7qrVEvwX3NKnCn5/HEwrcctAZP 8dwrJxWmnujSXmyzaAJ23SCwb4KJkNynnayAtGHtr7DfefywTliCWyTfLC3njNTx5h RNoxsQvplAB5BeD5hqJ7pOFGYa3bsvLk9pAcjNh2KkGyeSUaqw0e8ana39ENcZmRAZ N4fNzWZVz6LPQ== Received: by mail-ed1-f71.google.com with SMTP id c64-20020a509fc6000000b004a26cc7f6cbso4579522edf.4 for ; Tue, 11 Apr 2023 03:43:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681209820; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pRf5xzGSUbwksyzKh9EFSxutG5TUV/lwNKq2bZMboXc=; b=1qnKz497cJDMbx0yrcBKIMX/xpnt1ZK7br5wm+WUKOmHnq4OkoIuoc3SQUVb+wevjE YeszOsXcAWRnWJd+jXAEMB71dWNFGPCNS11Wc3iajsVIIUnn5E4ka3/iBPdtoNHCmj9Y l23fDgW1ESFgPyv6Mk5wG3bB8T4yc+gRGhkt3r6cyRKDZfgxD23H4x8gnzvm57jRNWeF Es2P01UB6kvIaCI5mf4HJL+ugRriaDkw5nOhQRCDY+QfqjHkfzsd2QgUJFk+5k9wH0/2 8N9kMwlMxaL52trrqtV7x8jMPvOYRuhizH8NO74XRpLUaMETYnZJ2NccBgTCUaTTDD4J lBEg== X-Gm-Message-State: AAQBX9cXr5bJ3KrGXWeoWVI5xZR4CeNeFwXBsVSvjH6rsKUCsWVF7CrE /ajZdC+7gdxwj0BpZ1rLWRw2s/1qQIERthTHXZy5uepmTAJrdtQXF1YP2v78BKZnpKniiqVrfqa C+4NYY4X83cYcqXv2BWee9N7LmjnxtXn07wlqwq45TQ== X-Received: by 2002:a17:907:2ced:b0:8ee:babc:d40b with SMTP id hz13-20020a1709072ced00b008eebabcd40bmr9069386ejc.58.1681209820504; Tue, 11 Apr 2023 03:43:40 -0700 (PDT) X-Received: by 2002:a17:907:2ced:b0:8ee:babc:d40b with SMTP id hz13-20020a1709072ced00b008eebabcd40bmr9069360ejc.58.1681209820244; Tue, 11 Apr 2023 03:43:40 -0700 (PDT) Received: from amikhalitsyn.. ([95.91.208.118]) by smtp.gmail.com with ESMTPSA id ne7-20020a1709077b8700b00948c320fcfdsm5921805ejc.202.2023.04.11.03.43.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Apr 2023 03:43:39 -0700 (PDT) From: Alexander Mikhalitsyn To: davem@davemloft.net Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Alexander Mikhalitsyn , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Leon Romanovsky , David Ahern , Arnd Bergmann , Kees Cook , Christian Brauner , Kuniyuki Iwashima , Lennart Poettering , Luca Boccassi , linux-arch@vger.kernel.org Subject: [PATCH net-next v3 3/4] net: core: add getsockopt SO_PEERPIDFD Date: Tue, 11 Apr 2023 12:42:30 +0200 Message-Id: <20230411104231.160837-4-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230411104231.160837-1-aleksandr.mikhalitsyn@canonical.com> References: <20230411104231.160837-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.5 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762877080882630051?= X-GMAIL-MSGID: =?utf-8?q?1762877080882630051?= Add SO_PEERPIDFD which allows to get pidfd of peer socket holder pidfd. This thing is direct analog of SO_PEERCRED which allows to get plain PID. Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Leon Romanovsky Cc: David Ahern Cc: Arnd Bergmann Cc: Kees Cook Cc: Christian Brauner Cc: Kuniyuki Iwashima Cc: Lennart Poettering Cc: Luca Boccassi Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-arch@vger.kernel.org Tested-by: Luca Boccassi Signed-off-by: Alexander Mikhalitsyn --- v3: - fixed possible fd leak (thanks to Christian Brauner) v2: According to review comments from Kuniyuki Iwashima and Christian Brauner: - use pidfd_create(..) retval as a result - whitespace change --- arch/alpha/include/uapi/asm/socket.h | 1 + arch/mips/include/uapi/asm/socket.h | 1 + arch/parisc/include/uapi/asm/socket.h | 1 + arch/sparc/include/uapi/asm/socket.h | 1 + include/uapi/asm-generic/socket.h | 1 + net/core/sock.c | 33 +++++++++++++++++++++++++ net/socket.c | 7 ++++++ tools/include/uapi/asm-generic/socket.h | 1 + 8 files changed, 46 insertions(+) diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index ff310613ae64..e94f621903fe 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -138,6 +138,7 @@ #define SO_RCVMARK 75 #define SO_PASSPIDFD 76 +#define SO_PEERPIDFD 77 #if !defined(__KERNEL__) diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 762dcb80e4ec..60ebaed28a4c 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -149,6 +149,7 @@ #define SO_RCVMARK 75 #define SO_PASSPIDFD 76 +#define SO_PEERPIDFD 77 #if !defined(__KERNEL__) diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index df16a3e16d64..be264c2b1a11 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -130,6 +130,7 @@ #define SO_RCVMARK 0x4049 #define SO_PASSPIDFD 0x404A +#define SO_PEERPIDFD 0x404B #if !defined(__KERNEL__) diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 6e2847804fea..682da3714686 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -131,6 +131,7 @@ #define SO_RCVMARK 0x0054 #define SO_PASSPIDFD 0x0055 +#define SO_PEERPIDFD 0x0056 #if !defined(__KERNEL__) diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index b76169fdb80b..8ce8a39a1e5f 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -133,6 +133,7 @@ #define SO_RCVMARK 75 #define SO_PASSPIDFD 76 +#define SO_PEERPIDFD 77 #if !defined(__KERNEL__) diff --git a/net/core/sock.c b/net/core/sock.c index 3f974246ba3e..2b040a69e355 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1763,6 +1763,39 @@ int sk_getsockopt(struct sock *sk, int level, int optname, goto lenout; } + case SO_PEERPIDFD: + { + struct pid *peer_pid; + struct file *pidfd_file = NULL; + int pidfd; + + if (len > sizeof(pidfd)) + len = sizeof(pidfd); + + spin_lock(&sk->sk_peer_lock); + peer_pid = get_pid(sk->sk_peer_pid); + spin_unlock(&sk->sk_peer_lock); + + pidfd = pidfd_prepare(peer_pid, 0, &pidfd_file); + + put_pid(peer_pid); + + if (copy_to_sockptr(optval, &pidfd, len) || + copy_to_sockptr(optlen, &len, sizeof(int))) { + if (pidfd >= 0) { + put_unused_fd(pidfd); + fput(pidfd_file); + } + + return -EFAULT; + } + + if (pidfd_file) + fd_install(pidfd, pidfd_file); + + return 0; + } + case SO_PEERGROUPS: { const struct cred *cred; diff --git a/net/socket.c b/net/socket.c index 9c1ef11de23f..505b85489354 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2248,6 +2248,13 @@ static bool sockopt_installs_fd(int level, int optname) default: return false; } + } else if (level == SOL_SOCKET) { + switch (optname) { + case SO_PEERPIDFD: + return true; + default: + return false; + } } return false; diff --git a/tools/include/uapi/asm-generic/socket.h b/tools/include/uapi/asm-generic/socket.h index fbbc4bf53ee3..54d9c8bf7c55 100644 --- a/tools/include/uapi/asm-generic/socket.h +++ b/tools/include/uapi/asm-generic/socket.h @@ -122,6 +122,7 @@ #define SO_RCVMARK 75 #define SO_PASSPIDFD 76 +#define SO_PEERPIDFD 77 #if !defined(__KERNEL__) From patchwork Tue Apr 11 10:42:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 81877 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2480303vqo; Tue, 11 Apr 2023 03:59:11 -0700 (PDT) X-Google-Smtp-Source: AKy350aZ5Dnyw+T7sdRl1URv1wsr/TJBWCoEQW2b5WHcLxGnRAJPcwMUwla1GtV9c5gCrJ/OPaRm X-Received: by 2002:aa7:988c:0:b0:636:1f93:a107 with SMTP id r12-20020aa7988c000000b006361f93a107mr2859276pfl.18.1681210750790; Tue, 11 Apr 2023 03:59:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681210750; cv=none; d=google.com; s=arc-20160816; b=R/y0ymmEuaivewdI2a2QS/u9jZgnWVCSZszeEH55CqoTK7OST0JhjenwggeHj27Csz FCTGHBn6L5d6Q7pOWtgBsab7YtY3rIcG/d72jDCsnha0vn2iJSVjyMFj8uBr7x0JszDO ty6ZAz3UfRJYc3B0aeEZUKAzMjozF/FxOMh7SmCFt9YKDbkhiv4n2Cyes75cCz1ZEQaP Pnd/XtG0L4O7G99NF+GmKLIUS7HL7vdqLnu1ekUALCDq6QCJINdCO3+UiRk/8vaLMxxU ArkaYDm0T2zPdxyJxT8Vej/QtER2G6MLEes2ndVpvHRpdu708XJigfqdx/+ZFSUcihHo SAfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=9OFnG70DkKWiYI7WkrGxo4LXdZLPfs21Ye1s1GRVjTU=; b=FRZyX9AUEJqaPx05yxJFNwEKRW+p8yGUXyPqXSBu1CjYoRu4yxHI53kJQNsTmS+Z5q Mq8FvCMNo518ECcCrhacwksnMf0vFe2+K4hW8GsIfac3WbFaZna9ErDBmLQWKAI6kEFs VcjVG9zBG8bpyK7pBSDBDHB3FUDzOBavGr+Yc9JbmvdQb052c+3s68PhOGSF4dxnN9Td i/NFpyrhTqXU/xoDWOuNGUbTE/37rEHVqftQss2XtwDJm+YHDAWbMqCCYAaQB2ZNSEAn /mMB5LzAumem8Gmq5JWkJMrwNAjYwku3X2fAF4M+wcZQ8yTv2x/aXDTV/J00//KLepgV oiQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b="t/1AZbD+"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z25-20020aa79f99000000b00639f1da9fa1si3264096pfr.172.2023.04.11.03.58.58; Tue, 11 Apr 2023 03:59:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b="t/1AZbD+"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229491AbjDKKoZ (ORCPT + 99 others); Tue, 11 Apr 2023 06:44:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229899AbjDKKoL (ORCPT ); Tue, 11 Apr 2023 06:44:11 -0400 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5ED4C358D for ; Tue, 11 Apr 2023 03:43:51 -0700 (PDT) Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 298083F23F for ; Tue, 11 Apr 2023 10:43:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1681209830; bh=9OFnG70DkKWiYI7WkrGxo4LXdZLPfs21Ye1s1GRVjTU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=t/1AZbD+2o4YVyFXicI4Vwo0fWmJ62qy/JMkPYpKm/ZhaaCa0Vxn0Epw5zqSnKK7o lOC0aI73ksVp92xBYYHvPwvdXv5Y5AdkOcuEEwNZQVFxyMNQ5aFeeKdVk1bbRSufwj MuU+GF2IpK0L3uG3q8GkdLAFYtmuXUi171nfmOyms5L9thNvblgoxGSQjzANZ9yvml 8shLBN3/+9KFcDdfM7i3F2bqFtDvHYADp8Zqhg8304yyryzYTr1Q+xRefjGi7gNCIp kB/a+7OXKgOlchjQcUrxp9o+8XVtAsxxLMoxVBXWbkGfiKkm4rP65o0H8m0XLWsGs8 PC1/mxzsGRFzQ== Received: by mail-ed1-f69.google.com with SMTP id v21-20020a509555000000b004ad062fee5eso4509703eda.17 for ; Tue, 11 Apr 2023 03:43:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681209828; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9OFnG70DkKWiYI7WkrGxo4LXdZLPfs21Ye1s1GRVjTU=; b=HwQDcCrINnnnTyXdP8znfgL2ORttgZr8lQi44TlCeohwO+6m91aVY2y9HGyPK2MQ96 aYieraJahhvA/kF+JAR4pPSpMFONG72CZXiTdBYsRFhWQyZ5jLoiqsrZI/q8pd1Ubwwn mAaWpEZPw0TLbNwMXyyOq1BOZforp/PkeL51ZfM8IxqdDeKNuZ1vVUYeDiXv8kO10nbX 4FaXrrmci4oOStCu0bWTEYUFJ0G678p9j2mW8OvVR82BbO6Ynb5Emo2on5C2Louk9/Uu L12c2fiaZVb67EVoPjetpqwdGDiKtqpcoi2EY6DRDtGJw5qu+UEWI26ihzExvRnLCqRA VzwA== X-Gm-Message-State: AAQBX9fmeIe8Kn2T0vE9FwXOGMmtYIBtzsEr7DB0pt8lbwINLSKnJqZj BrRnWrIDRiP+guSDzSy2ZsxPkXRU06OUFhjHK8R0g1qHRyoywKadlkENF07afnx2VvxHZPVC7AC oA7GqWJ/ccunES43AlQZ2rNXFk+FyU/Gx3SR6yXvBLA== X-Received: by 2002:a17:906:2556:b0:94a:a887:c29f with SMTP id j22-20020a170906255600b0094aa887c29fmr1899824ejb.68.1681209828471; Tue, 11 Apr 2023 03:43:48 -0700 (PDT) X-Received: by 2002:a17:906:2556:b0:94a:a887:c29f with SMTP id j22-20020a170906255600b0094aa887c29fmr1899802ejb.68.1681209828078; Tue, 11 Apr 2023 03:43:48 -0700 (PDT) Received: from amikhalitsyn.. ([95.91.208.118]) by smtp.gmail.com with ESMTPSA id ne7-20020a1709077b8700b00948c320fcfdsm5921805ejc.202.2023.04.11.03.43.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Apr 2023 03:43:47 -0700 (PDT) From: Alexander Mikhalitsyn To: davem@davemloft.net Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Alexander Mikhalitsyn , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Leon Romanovsky , David Ahern , Arnd Bergmann , Kees Cook , Christian Brauner , Kuniyuki Iwashima , linux-arch@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next v3 4/4] selftests: net: add SCM_PIDFD / SO_PEERPIDFD test Date: Tue, 11 Apr 2023 12:42:31 +0200 Message-Id: <20230411104231.160837-5-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230411104231.160837-1-aleksandr.mikhalitsyn@canonical.com> References: <20230411104231.160837-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.5 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762877244317720324?= X-GMAIL-MSGID: =?utf-8?q?1762877244317720324?= Basic test to check consistency between: - SCM_CREDENTIALS and SCM_PIDFD - SO_PEERCRED and SO_PEERPIDFD Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Leon Romanovsky Cc: David Ahern Cc: Arnd Bergmann Cc: Kees Cook Cc: Christian Brauner Cc: Kuniyuki Iwashima Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-arch@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Signed-off-by: Alexander Mikhalitsyn --- v3: - started using kselftest lib (thanks to Kuniyuki Iwashima for suggestion/review) - now test covers abstract sockets too and SOCK_DGRAM sockets --- tools/testing/selftests/net/.gitignore | 1 + tools/testing/selftests/net/af_unix/Makefile | 2 +- .../testing/selftests/net/af_unix/scm_pidfd.c | 430 ++++++++++++++++++ 3 files changed, 432 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/net/af_unix/scm_pidfd.c diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore index 80f06aa62034..83fd1ebd34ec 100644 --- a/tools/testing/selftests/net/.gitignore +++ b/tools/testing/selftests/net/.gitignore @@ -26,6 +26,7 @@ reuseport_bpf_cpu reuseport_bpf_numa reuseport_dualstack rxtimestamp +scm_pidfd sk_bind_sendto_listen sk_connect_zero_addr socket diff --git a/tools/testing/selftests/net/af_unix/Makefile b/tools/testing/selftests/net/af_unix/Makefile index 1e4b397cece6..f5ca9da8c4d5 100644 --- a/tools/testing/selftests/net/af_unix/Makefile +++ b/tools/testing/selftests/net/af_unix/Makefile @@ -1,3 +1,3 @@ -TEST_GEN_PROGS := diag_uid test_unix_oob unix_connect +TEST_GEN_PROGS := diag_uid test_unix_oob unix_connect scm_pidfd include ../../lib.mk diff --git a/tools/testing/selftests/net/af_unix/scm_pidfd.c b/tools/testing/selftests/net/af_unix/scm_pidfd.c new file mode 100644 index 000000000000..a86222143d79 --- /dev/null +++ b/tools/testing/selftests/net/af_unix/scm_pidfd.c @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../kselftest_harness.h" + +#define clean_errno() (errno == 0 ? "None" : strerror(errno)) +#define log_err(MSG, ...) \ + fprintf(stderr, "(%s:%d: errno: %s) " MSG "\n", __FILE__, __LINE__, \ + clean_errno(), ##__VA_ARGS__) + +#ifndef SCM_PIDFD +#define SCM_PIDFD 0x04 +#endif + +static void child_die() +{ + exit(1); +} + +static int safe_int(const char *numstr, int *converted) +{ + char *err = NULL; + long sli; + + errno = 0; + sli = strtol(numstr, &err, 0); + if (errno == ERANGE && (sli == LONG_MAX || sli == LONG_MIN)) + return -ERANGE; + + if (errno != 0 && sli == 0) + return -EINVAL; + + if (err == numstr || *err != '\0') + return -EINVAL; + + if (sli > INT_MAX || sli < INT_MIN) + return -ERANGE; + + *converted = (int)sli; + return 0; +} + +static int char_left_gc(const char *buffer, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + if (buffer[i] == ' ' || buffer[i] == '\t') + continue; + + return i; + } + + return 0; +} + +static int char_right_gc(const char *buffer, size_t len) +{ + int i; + + for (i = len - 1; i >= 0; i--) { + if (buffer[i] == ' ' || buffer[i] == '\t' || + buffer[i] == '\n' || buffer[i] == '\0') + continue; + + return i + 1; + } + + return 0; +} + +static char *trim_whitespace_in_place(char *buffer) +{ + buffer += char_left_gc(buffer, strlen(buffer)); + buffer[char_right_gc(buffer, strlen(buffer))] = '\0'; + return buffer; +} + +/* borrowed (with all helpers) from pidfd/pidfd_open_test.c */ +static pid_t get_pid_from_fdinfo_file(int pidfd, const char *key, size_t keylen) +{ + int ret; + char path[512]; + FILE *f; + size_t n = 0; + pid_t result = -1; + char *line = NULL; + + snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", pidfd); + + f = fopen(path, "re"); + if (!f) + return -1; + + while (getline(&line, &n, f) != -1) { + char *numstr; + + if (strncmp(line, key, keylen)) + continue; + + numstr = trim_whitespace_in_place(line + 4); + ret = safe_int(numstr, &result); + if (ret < 0) + goto out; + + break; + } + +out: + free(line); + fclose(f); + return result; +} + +static int cmsg_check(int fd) +{ + struct msghdr msg = { 0 }; + struct cmsghdr *cmsg; + struct iovec iov; + struct ucred *ucred = NULL; + int data = 0; + char control[CMSG_SPACE(sizeof(struct ucred)) + + CMSG_SPACE(sizeof(int))] = { 0 }; + int *pidfd = NULL; + pid_t parent_pid; + int err; + + iov.iov_base = &data; + iov.iov_len = sizeof(data); + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + + err = recvmsg(fd, &msg, 0); + if (err < 0) { + log_err("recvmsg"); + return 1; + } + + if (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) { + log_err("recvmsg: truncated"); + return 1; + } + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_PIDFD) { + if (cmsg->cmsg_len < sizeof(*pidfd)) { + log_err("CMSG parse: SCM_PIDFD wrong len"); + return 1; + } + + pidfd = (void *)CMSG_DATA(cmsg); + } + + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_CREDENTIALS) { + if (cmsg->cmsg_len < sizeof(*ucred)) { + log_err("CMSG parse: SCM_CREDENTIALS wrong len"); + return 1; + } + + ucred = (void *)CMSG_DATA(cmsg); + } + } + + /* send(pfd, "x", sizeof(char), 0) */ + if (data != 'x') { + log_err("recvmsg: data corruption"); + return 1; + } + + if (!pidfd) { + log_err("CMSG parse: SCM_PIDFD not found"); + return 1; + } + + if (!ucred) { + log_err("CMSG parse: SCM_CREDENTIALS not found"); + return 1; + } + + /* pidfd from SCM_PIDFD should point to the parent process PID */ + parent_pid = + get_pid_from_fdinfo_file(*pidfd, "Pid:", sizeof("Pid:") - 1); + if (parent_pid != getppid()) { + log_err("wrong SCM_PIDFD %d != %d", parent_pid, getppid()); + return 1; + } + + return 0; +} + +struct sock_addr { + char sock_name[32]; + struct sockaddr_un listen_addr; + socklen_t addrlen; +}; + +FIXTURE(scm_pidfd) +{ + int server; + pid_t client_pid; + int startup_pipe[2]; + struct sock_addr server_addr; + struct sock_addr *client_addr; +}; + +FIXTURE_VARIANT(scm_pidfd) +{ + int type; + bool abstract; +}; + +FIXTURE_VARIANT_ADD(scm_pidfd, stream_pathname) +{ + .type = SOCK_STREAM, + .abstract = 0, +}; + +FIXTURE_VARIANT_ADD(scm_pidfd, stream_abstract) +{ + .type = SOCK_STREAM, + .abstract = 1, +}; + +FIXTURE_VARIANT_ADD(scm_pidfd, dgram_pathname) +{ + .type = SOCK_DGRAM, + .abstract = 0, +}; + +FIXTURE_VARIANT_ADD(scm_pidfd, dgram_abstract) +{ + .type = SOCK_DGRAM, + .abstract = 1, +}; + +FIXTURE_SETUP(scm_pidfd) +{ + self->client_addr = mmap(NULL, sizeof(*self->client_addr), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + ASSERT_NE(MAP_FAILED, self->client_addr); +} + +FIXTURE_TEARDOWN(scm_pidfd) +{ + close(self->server); + + kill(self->client_pid, SIGKILL); + waitpid(self->client_pid, NULL, 0); + + if (!variant->abstract) { + unlink(self->server_addr.sock_name); + unlink(self->client_addr->sock_name); + } +} + +static void fill_sockaddr(struct sock_addr *addr, bool abstract) +{ + char *sun_path_buf = (char *)&addr->listen_addr.sun_path; + + addr->listen_addr.sun_family = AF_UNIX; + addr->addrlen = offsetof(struct sockaddr_un, sun_path); + snprintf(addr->sock_name, sizeof(addr->sock_name), "scm_pidfd_%d", getpid()); + addr->addrlen += strlen(addr->sock_name); + if (abstract) { + *sun_path_buf = '\0'; + addr->addrlen++; + sun_path_buf++; + } else { + unlink(addr->sock_name); + } + memcpy(sun_path_buf, addr->sock_name, strlen(addr->sock_name)); +} + +static void client(FIXTURE_DATA(scm_pidfd) *self, + const FIXTURE_VARIANT(scm_pidfd) *variant) +{ + int err; + int cfd; + socklen_t len; + struct ucred peer_cred; + int peer_pidfd; + pid_t peer_pid; + int on = 0; + + cfd = socket(AF_UNIX, variant->type, 0); + if (cfd < 0) { + log_err("socket"); + child_die(); + } + + if (variant->type == SOCK_DGRAM) { + fill_sockaddr(self->client_addr, variant->abstract); + + if (bind(cfd, (struct sockaddr *)&self->client_addr->listen_addr, self->client_addr->addrlen)) { + log_err("bind"); + child_die(); + } + } + + if (connect(cfd, (struct sockaddr *)&self->server_addr.listen_addr, + self->server_addr.addrlen) != 0) { + log_err("connect"); + child_die(); + } + + on = 1; + if (setsockopt(cfd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) { + log_err("Failed to set SO_PASSCRED"); + child_die(); + } + + if (setsockopt(cfd, SOL_SOCKET, SO_PASSPIDFD, &on, sizeof(on))) { + log_err("Failed to set SO_PASSPIDFD"); + child_die(); + } + + close(self->startup_pipe[1]); + + if (cmsg_check(cfd)) { + log_err("cmsg_check failed"); + child_die(); + } + + /* skip further for SOCK_DGRAM as it's not applicable */ + if (variant->type == SOCK_DGRAM) + return; + + len = sizeof(peer_cred); + if (getsockopt(cfd, SOL_SOCKET, SO_PEERCRED, &peer_cred, &len)) { + log_err("Failed to get SO_PEERCRED"); + child_die(); + } + + len = sizeof(peer_pidfd); + if (getsockopt(cfd, SOL_SOCKET, SO_PEERPIDFD, &peer_pidfd, &len)) { + log_err("Failed to get SO_PEERPIDFD"); + child_die(); + } + + /* pid from SO_PEERCRED should point to the parent process PID */ + if (peer_cred.pid != getppid()) { + log_err("peer_cred.pid != getppid(): %d != %d", peer_cred.pid, getppid()); + child_die(); + } + + peer_pid = get_pid_from_fdinfo_file(peer_pidfd, + "Pid:", sizeof("Pid:") - 1); + if (peer_pid != peer_cred.pid) { + log_err("peer_pid != peer_cred.pid: %d != %d", peer_pid, peer_cred.pid); + child_die(); + } +} + +TEST_F(scm_pidfd, test) +{ + int err; + int pfd; + int child_status = 0; + + self->server = socket(AF_UNIX, variant->type, 0); + ASSERT_NE(-1, self->server); + + fill_sockaddr(&self->server_addr, variant->abstract); + + err = bind(self->server, (struct sockaddr *)&self->server_addr.listen_addr, self->server_addr.addrlen); + ASSERT_EQ(0, err); + + if (variant->type == SOCK_STREAM) { + err = listen(self->server, 1); + ASSERT_EQ(0, err); + } + + err = pipe(self->startup_pipe); + ASSERT_NE(-1, err); + + self->client_pid = fork(); + ASSERT_NE(-1, self->client_pid); + if (self->client_pid == 0) { + close(self->server); + close(self->startup_pipe[0]); + client(self, variant); + exit(0); + } + close(self->startup_pipe[1]); + + if (variant->type == SOCK_STREAM) { + pfd = accept(self->server, NULL, NULL); + ASSERT_NE(-1, pfd); + } else { + pfd = self->server; + } + + /* wait until the child arrives at checkpoint */ + read(self->startup_pipe[0], &err, sizeof(int)); + close(self->startup_pipe[0]); + + if (variant->type == SOCK_DGRAM) { + err = sendto(pfd, "x", sizeof(char), 0, (struct sockaddr *)&self->client_addr->listen_addr, self->client_addr->addrlen); + ASSERT_NE(-1, err); + } else { + err = send(pfd, "x", sizeof(char), 0); + ASSERT_NE(-1, err); + } + + close(pfd); + waitpid(self->client_pid, &child_status, 0); + ASSERT_EQ(0, WIFEXITED(child_status) ? WEXITSTATUS(child_status) : 1); +} + +TEST_HARNESS_MAIN