Commit 718e6b51 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by David S. Miller

af_unix: Fix msg_controllen test in scm_pidfd_recv() for MSG_CMSG_COMPAT.

Heiko Carstens reported that SCM_PIDFD does not work with MSG_CMSG_COMPAT
because scm_pidfd_recv() always checks msg_controllen against sizeof(struct
cmsghdr).

We need to use sizeof(struct compat_cmsghdr) for the compat case.

Fixes: 5e2ff670 ("scm: add SO_PASSPIDFD and SCM_PIDFD")
Reported-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Closes: https://lore.kernel.org/netdev/20230901200517.8742-A-hca@linux.ibm.com/Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Tested-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Reviewed-by: default avatarAlexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Reviewed-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Acked-by: default avatarChristian Brauner <brauner@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 52450087
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/pid.h> #include <linux/pid.h>
#include <linux/nsproxy.h> #include <linux/nsproxy.h>
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <net/compat.h>
/* Well, we should have at least one descriptor open /* Well, we should have at least one descriptor open
* to accept passed FDs 8) * to accept passed FDs 8)
...@@ -123,14 +124,17 @@ static inline bool scm_has_secdata(struct socket *sock) ...@@ -123,14 +124,17 @@ static inline bool scm_has_secdata(struct socket *sock)
static __inline__ void scm_pidfd_recv(struct msghdr *msg, struct scm_cookie *scm) static __inline__ void scm_pidfd_recv(struct msghdr *msg, struct scm_cookie *scm)
{ {
struct file *pidfd_file = NULL; struct file *pidfd_file = NULL;
int pidfd; int len, pidfd;
/* /* put_cmsg() doesn't return an error if CMSG is truncated,
* put_cmsg() doesn't return an error if CMSG is truncated,
* that's why we need to opencode these checks here. * that's why we need to opencode these checks here.
*/ */
if ((msg->msg_controllen <= sizeof(struct cmsghdr)) || if (msg->msg_flags & MSG_CMSG_COMPAT)
(msg->msg_controllen - sizeof(struct cmsghdr)) < sizeof(int)) { len = sizeof(struct compat_cmsghdr) + sizeof(int);
else
len = sizeof(struct cmsghdr) + sizeof(int);
if (msg->msg_controllen < len) {
msg->msg_flags |= MSG_CTRUNC; msg->msg_flags |= MSG_CTRUNC;
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment