[Patch?==?utf-8?q? 2/5] Problems with upstream SPECTRE mitigation found in sendmsg/recvmsg syscalls
François Legal
francois.legal at thom.fr.eu.org
Mon Dec 7 11:58:35 CET 2020
From: François LEGAL <devel at thom.fr.eu.org>
Add copy_from_user call on struct user_msghdr in case fd is a user fd.
Signed-off-by: François LEGAL <devel at thom.fr.eu.org>
---
kernel/drivers/can/rtcan_raw.c | 37 +++++++++++++++++++++++++++++--------
1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
index 693b927..ef05ae2 100644
--- a/kernel/drivers/can/rtcan_raw.c
+++ b/kernel/drivers/can/rtcan_raw.c
@@ -527,12 +527,12 @@ do { \
} while (0)
ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
- struct user_msghdr *msg, int flags)
+ struct user_msghdr *u_msg, int flags)
{
struct rtcan_socket *sock = rtdm_fd_to_private(fd);
struct sockaddr_can scan;
nanosecs_rel_t timeout;
- struct iovec *iov = (struct iovec *)msg->msg_iov;
+ struct iovec *iov;
struct iovec iov_buf;
can_frame_t frame;
nanosecs_abs_t timestamp = 0;
@@ -543,8 +543,17 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
size_t first_part_size;
size_t payload_size;
rtdm_lockctx_t lock_ctx;
+ struct user_msghdr _msg, *msg;
int ret;
+ if (rtdm_fd_is_user(fd)) {
+ if ((ret = rtdm_copy_from_user(fd, & _msg, u_msg, sizeof (struct user_msghdr))) != 0)
+ return -ret;
+ else
+ msg = & _msg;
+ } else
+ msg = u_msg;
+
/* Clear frame memory location */
memset(&frame, 0, sizeof(can_frame_t));
@@ -582,7 +591,8 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
return -EFAULT;
iov = &iov_buf;
- }
+ } else
+ iov = (struct iovec *)msg->msg_iov;
/* Check size of buffer */
if (iov->iov_len < sizeof(can_frame_t))
@@ -763,12 +773,12 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
- const struct user_msghdr *msg, int flags)
+ const struct user_msghdr *u_msg, int flags)
{
struct rtcan_socket *sock = rtdm_fd_to_private(fd);
- struct sockaddr_can *scan = (struct sockaddr_can *)msg->msg_name;
+ struct sockaddr_can *scan;
struct sockaddr_can scan_buf;
- struct iovec *iov = (struct iovec *)msg->msg_iov;
+ struct iovec *iov;
struct iovec iov_buf;
can_frame_t *frame;
can_frame_t frame_buf;
@@ -776,10 +786,19 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
nanosecs_rel_t timeout = 0;
struct tx_wait_queue tx_wait;
struct rtcan_device *dev;
+ struct user_msghdr _msg;
+ const struct user_msghdr *msg;
int ifindex = 0;
int ret = 0;
spl_t s;
+ if (rtdm_fd_is_user(fd)) {
+ if ((ret = rtdm_copy_from_user(fd, & _msg, u_msg, sizeof (struct user_msghdr))) != 0)
+ return -ret;
+ else
+ msg = & _msg;
+ } else
+ msg = u_msg;
if (flags & MSG_OOB) /* Mirror BSD error message compatibility */
return -EOPNOTSUPP;
@@ -821,7 +840,8 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
return -EFAULT;
scan = &scan_buf;
- }
+ } else
+ scan = (struct sockaddr_can *)msg->msg_name;
/* Check address family */
if (scan->can_family != AF_CAN)
@@ -839,7 +859,8 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
return -EFAULT;
iov = &iov_buf;
- }
+ } else
+ iov = (struct iovec *)msg->msg_iov;
/* Check size of buffer */
if (iov->iov_len != sizeof(can_frame_t))
More information about the Xenomai
mailing list