diff mbox series

[net-next] net: scm: introduce and use scm_recv_unix helper

Message ID 20230626215951.563715-1-aleksandr.mikhalitsyn@canonical.com (mailing list archive)
State New, archived
Headers show
Series [net-next] net: scm: introduce and use scm_recv_unix helper | expand

Checks

Context Check Description
tedd_an/pre-ci_am fail error: patch failed: net/unix/af_unix.c:2808 error: net/unix/af_unix.c: patch does not apply hint: Use 'git am --show-current-patch' to see the failed patch

Commit Message

Aleksandr Mikhalitsyn June 26, 2023, 9:59 p.m. UTC
Recently, our friends from bluetooth subsystem reported
[1] that after ("scm: add SO_PASSPIDFD and SCM_PIDFD")
scm_recv helper become unusable in kernel modules (because it
uses unexported pidfd_prepare() API).

We were aware of this issue and workarounded it in a hard way
by ("af_unix: Kconfig: make CONFIG_UNIX bool").

But recently a new functionality was added in the scope of
817efd3cad74 ("Bluetooth: hci_sock: Forward credentials to monitor")
and after that bluetooth can't be compiled as a kernel module.

After some discussion in [1] we decided to split scm_recv into
two helpers, one won't support SCM_PIDFD (used for unix sockets),
and another one will be completely the same as it was before
("scm: add SO_PASSPIDFD and SCM_PIDFD").

[1] https://lore.kernel.org/lkml/CAJqdLrpFcga4n7wxBhsFqPQiN8PKFVr6U10fKcJ9W7AcZn+o6Q@mail.gmail.com/

Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Kuniyuki Iwashima <kuniyu@amazon.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-bluetooth@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
---
 include/net/scm.h  | 35 +++++++++++++++++++++++++----------
 net/unix/af_unix.c |  4 ++--
 2 files changed, 27 insertions(+), 12 deletions(-)

Comments

bluez.test.bot@gmail.com June 26, 2023, 10:13 p.m. UTC | #1
This is an automated email and please do not reply to this email.

Dear Submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.

----- Output -----

error: patch failed: net/unix/af_unix.c:2808
error: net/unix/af_unix.c: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch

Please resolve the issue and submit the patches again.


---
Regards,
Linux Bluetooth
diff mbox series

Patch

diff --git a/include/net/scm.h b/include/net/scm.h
index c67f765a165b..409b8efda2c9 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -151,8 +151,8 @@  static __inline__ void scm_pidfd_recv(struct msghdr *msg, struct scm_cookie *scm
 		fd_install(pidfd, pidfd_file);
 }
 
-static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
-				struct scm_cookie *scm, int flags)
+static inline bool __scm_recv_common(struct socket *sock, struct msghdr *msg,
+					 struct scm_cookie *scm, int flags)
 {
 	if (!msg->msg_control) {
 		if (test_bit(SOCK_PASSCRED, &sock->flags) ||
@@ -160,7 +160,7 @@  static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		    scm->fp || scm_has_secdata(sock))
 			msg->msg_flags |= MSG_CTRUNC;
 		scm_destroy(scm);
-		return;
+		return false;
 	}
 
 	if (test_bit(SOCK_PASSCRED, &sock->flags)) {
@@ -173,19 +173,34 @@  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))
-		scm_pidfd_recv(msg, scm);
+	scm_passec(sock, msg, scm);
 
-	scm_destroy_cred(scm);
+	if (scm->fp)
+		scm_detach_fds(msg, scm);
 
-	scm_passec(sock, msg, scm);
+	return true;
+}
 
-	if (!scm->fp)
+static inline void scm_recv(struct socket *sock, struct msghdr *msg,
+				struct scm_cookie *scm, int flags)
+{
+	if (!__scm_recv_common(sock, msg, scm, flags))
 		return;
-	
-	scm_detach_fds(msg, scm);
+
+	scm_destroy_cred(scm);
 }
 
+static inline void scm_recv_unix(struct socket *sock, struct msghdr *msg,
+				     struct scm_cookie *scm, int flags)
+{
+	if (!__scm_recv_common(sock, msg, scm, flags))
+		return;
+
+	if (test_bit(SOCK_PASSPIDFD, &sock->flags))
+		scm_pidfd_recv(msg, scm);
+
+	scm_destroy_cred(scm);
+}
 
 #endif /* __LINUX_NET_SCM_H */
 
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index f2f234f0b92c..20ac83e012e4 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2427,7 +2427,7 @@  int __unix_dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t size,
 	}
 	err = (flags & MSG_TRUNC) ? skb->len - skip : size;
 
-	scm_recv(sock, msg, &scm, flags);
+	scm_recv_unix(sock, msg, &scm, flags);
 
 out_free:
 	skb_free_datagram(sk, skb);
@@ -2808,7 +2808,7 @@  static int unix_stream_read_generic(struct unix_stream_read_state *state,
 
 	mutex_unlock(&u->iolock);
 	if (state->msg && check_creds)
-		scm_recv(sock, state->msg, &scm, flags);
+		scm_recv_unix(sock, state->msg, &scm, flags);
 	else
 		scm_destroy(&scm);
 out: