[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