Skip to content

Commit a9c49cc

Browse files
mihalicynkuba-moo
authored andcommitted
net: scm: introduce and use scm_recv_unix helper
Recently, our friends from bluetooth subsystem reported [1] that after commit 5e2ff67 ("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 commit 97154bc ("af_unix: Kconfig: make CONFIG_UNIX bool"). But recently a new functionality was added in the scope of commit 817efd3 ("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 commit 5e2ff67 ("scm: add SO_PASSPIDFD and SCM_PIDFD"). Link: https://lore.kernel.org/lkml/CAJqdLrpFcga4n7wxBhsFqPQiN8PKFVr6U10fKcJ9W7AcZn+o6Q@mail.gmail.com/ [1] Fixes: 5e2ff67 ("scm: add SO_PASSPIDFD and SCM_PIDFD") Signed-off-by: Alexander Mikhalitsyn <[email protected]> Reviewed-by: Kuniyuki Iwashima <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 603fc57 commit a9c49cc

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

include/net/scm.h

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,16 @@ static __inline__ void scm_pidfd_recv(struct msghdr *msg, struct scm_cookie *scm
153153
fd_install(pidfd, pidfd_file);
154154
}
155155

156-
static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
157-
struct scm_cookie *scm, int flags)
156+
static inline bool __scm_recv_common(struct socket *sock, struct msghdr *msg,
157+
struct scm_cookie *scm, int flags)
158158
{
159159
if (!msg->msg_control) {
160160
if (test_bit(SOCK_PASSCRED, &sock->flags) ||
161161
test_bit(SOCK_PASSPIDFD, &sock->flags) ||
162162
scm->fp || scm_has_secdata(sock))
163163
msg->msg_flags |= MSG_CTRUNC;
164164
scm_destroy(scm);
165-
return;
165+
return false;
166166
}
167167

168168
if (test_bit(SOCK_PASSCRED, &sock->flags)) {
@@ -175,19 +175,34 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
175175
put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
176176
}
177177

178-
if (test_bit(SOCK_PASSPIDFD, &sock->flags))
179-
scm_pidfd_recv(msg, scm);
178+
scm_passec(sock, msg, scm);
180179

181-
scm_destroy_cred(scm);
180+
if (scm->fp)
181+
scm_detach_fds(msg, scm);
182182

183-
scm_passec(sock, msg, scm);
183+
return true;
184+
}
184185

185-
if (!scm->fp)
186+
static inline void scm_recv(struct socket *sock, struct msghdr *msg,
187+
struct scm_cookie *scm, int flags)
188+
{
189+
if (!__scm_recv_common(sock, msg, scm, flags))
186190
return;
187-
188-
scm_detach_fds(msg, scm);
191+
192+
scm_destroy_cred(scm);
189193
}
190194

195+
static inline void scm_recv_unix(struct socket *sock, struct msghdr *msg,
196+
struct scm_cookie *scm, int flags)
197+
{
198+
if (!__scm_recv_common(sock, msg, scm, flags))
199+
return;
200+
201+
if (test_bit(SOCK_PASSPIDFD, &sock->flags))
202+
scm_pidfd_recv(msg, scm);
203+
204+
scm_destroy_cred(scm);
205+
}
191206

192207
#endif /* __LINUX_NET_SCM_H */
193208

net/unix/af_unix.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,7 +2427,7 @@ int __unix_dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t size,
24272427
}
24282428
err = (flags & MSG_TRUNC) ? skb->len - skip : size;
24292429

2430-
scm_recv(sock, msg, &scm, flags);
2430+
scm_recv_unix(sock, msg, &scm, flags);
24312431

24322432
out_free:
24332433
skb_free_datagram(sk, skb);
@@ -2808,7 +2808,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
28082808

28092809
mutex_unlock(&u->iolock);
28102810
if (state->msg)
2811-
scm_recv(sock, state->msg, &scm, flags);
2811+
scm_recv_unix(sock, state->msg, &scm, flags);
28122812
else
28132813
scm_destroy(&scm);
28142814
out:

0 commit comments

Comments
 (0)