All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Enablement of compat tests in CI
@ 2022-08-18  7:14 Florian Bezdeka
  2022-08-18  7:14 ` [PATCH 1/3] rtnet: Enable compat ioctl interface Florian Bezdeka
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Florian Bezdeka @ 2022-08-18  7:14 UTC (permalink / raw)
  To: xenomai; +Cc: jan.kiszka, Florian Bezdeka

Hi all,

this is a spin-off out of my y2038 queue. This helps to shorten the
y2038 stuff. The following 3 patches are necessary for getting the smokey 
testsuite sucessfully running in compat mode.

The necessary adjustments to the CI infrastructure (part of the
xenomai-images project) will follow soon.

At the end the following issue will be resolved: 
https://gitlab.com/Xenomai/xenomai-hacker-space/-/issues/21

Best regards,
Florian

Florian Bezdeka (3):
  rtnet: Enable compat ioctl interface
  drivers/rtcan: Implement compat support for the rtcan driver
  drivers/net/stack/ipv4/udp/udp.c: Add compat support

 include/cobalt/kernel/rtdm/fd.h         |  16 ++++
 kernel/cobalt/rtdm/drvlib.c             |  17 +---
 kernel/cobalt/rtdm/fd.c                 | 122 ++++++++++++++++++++++++
 kernel/drivers/can/rtcan_raw.c          |  42 ++++----
 kernel/drivers/net/stack/ipv4/udp/udp.c |  29 +++---
 kernel/drivers/net/stack/rtnet_chrdev.c |   1 +
 6 files changed, 174 insertions(+), 53 deletions(-)

-- 
2.37.2


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/3] rtnet: Enable compat ioctl interface
  2022-08-18  7:14 [PATCH 0/3] Enablement of compat tests in CI Florian Bezdeka
@ 2022-08-18  7:14 ` Florian Bezdeka
  2022-09-05 11:49   ` Jan Kiszka
  2022-08-18  7:14 ` [PATCH 2/3] drivers/rtcan: Implement compat support for the rtcan driver Florian Bezdeka
  2022-08-18  7:14 ` [PATCH 3/3] drivers/net/stack/ipv4/udp/udp.c: Add compat support Florian Bezdeka
  2 siblings, 1 reply; 8+ messages in thread
From: Florian Bezdeka @ 2022-08-18  7:14 UTC (permalink / raw)
  To: xenomai; +Cc: jan.kiszka, Florian Bezdeka

Running rtnet for compat applications failed because the compat ioctl
interface was not activated.

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 kernel/drivers/net/stack/rtnet_chrdev.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/drivers/net/stack/rtnet_chrdev.c b/kernel/drivers/net/stack/rtnet_chrdev.c
index 9457661a1..fa859c3bc 100644
--- a/kernel/drivers/net/stack/rtnet_chrdev.c
+++ b/kernel/drivers/net/stack/rtnet_chrdev.c
@@ -195,6 +195,7 @@ void rtnet_unregister_ioctls(struct rtnet_ioctls *ioctls)
 static struct file_operations rtnet_fops = {
 	.owner = THIS_MODULE,
 	.unlocked_ioctl = rtnet_ioctl,
+	.compat_ioctl = rtnet_ioctl,
 };
 
 static struct miscdevice rtnet_chr_misc_dev = {
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/3] drivers/rtcan: Implement compat support for the rtcan driver
  2022-08-18  7:14 [PATCH 0/3] Enablement of compat tests in CI Florian Bezdeka
  2022-08-18  7:14 ` [PATCH 1/3] rtnet: Enable compat ioctl interface Florian Bezdeka
@ 2022-08-18  7:14 ` Florian Bezdeka
  2022-09-05 11:44   ` Jan Kiszka
  2022-08-18  7:14 ` [PATCH 3/3] drivers/net/stack/ipv4/udp/udp.c: Add compat support Florian Bezdeka
  2 siblings, 1 reply; 8+ messages in thread
From: Florian Bezdeka @ 2022-08-18  7:14 UTC (permalink / raw)
  To: xenomai; +Cc: jan.kiszka, Florian Bezdeka

Once Xenomai was running as compat application (=32bit applicaiton over
64bit kernel) the can smokey test failed. This patch fixes the test by
implementing the necessary compat bits.

Affected ioctls:
  - _RTIOC_BIND
  - _RTIOC_SETSOCKOPT

Affected syscalls:
  - recvmsg
  - sendmsg

Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 include/cobalt/kernel/rtdm/fd.h |  16 +++++
 kernel/cobalt/rtdm/drvlib.c     |  17 +----
 kernel/cobalt/rtdm/fd.c         | 122 ++++++++++++++++++++++++++++++++
 kernel/drivers/can/rtcan_raw.c  |  42 +++++------
 4 files changed, 157 insertions(+), 40 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
index 058a9c638..176c67e22 100644
--- a/include/cobalt/kernel/rtdm/fd.h
+++ b/include/cobalt/kernel/rtdm/fd.h
@@ -29,6 +29,8 @@
 struct vm_area_struct;
 struct rtdm_fd;
 struct _rtdm_mmap_request;
+struct _rtdm_setsockaddr_args;
+struct _rtdm_setsockopt_args;
 struct xnselector;
 struct cobalt_ppd;
 struct rtdm_device;
@@ -403,6 +405,20 @@ int rtdm_fd_valid_p(int ufd);
 int rtdm_fd_select(int ufd, struct xnselector *selector,
 		   unsigned int type);
 
+int rtdm_fd_get_setsockaddr_args(struct rtdm_fd *fd,
+				 struct _rtdm_setsockaddr_args *dst,
+				 const void *src);
+
+int rtdm_fd_get_setsockopt_args(struct rtdm_fd *fd,
+				struct _rtdm_setsockopt_args *dst,
+				const void *src);
+
+int rtdm_fd_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
+		      const struct user_msghdr *msg, bool rw);
+
+int rtdm_fd_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
+		      const struct user_msghdr *msg);
+
 int rtdm_device_new_fd(struct rtdm_fd *fd, int ufd,
 		struct rtdm_device *dev);
 
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index 4eaf3a57c..30455c3d7 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -2211,14 +2211,7 @@ int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
 		return 0;
 	}
 
-#ifdef CONFIG_XENO_ARCH_SYS3264
-	if (rtdm_fd_is_compat(fd))
-		return sys32_get_iovec(iov,
-			       (struct compat_iovec __user *)msg->msg_iov,
-			       msg->msg_iovlen);
-#endif
-
-	return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
+	return rtdm_fd_get_iovec(fd, iov, msg, false);
 }
 EXPORT_SYMBOL_GPL(rtdm_get_iovec);
 
@@ -2233,13 +2226,7 @@ int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
 		memcpy(msg->msg_iov, iov, len);
 		ret = 0;
 	} else
-#ifdef CONFIG_XENO_ARCH_SYS3264
-		if (rtdm_fd_is_compat(fd))
-			ret = sys32_put_iovec((struct compat_iovec __user *)msg->msg_iov,
-					      iov, msg->msg_iovlen);
-		else
-#endif
-			ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
+		ret = rtdm_fd_put_iovec(fd, iov, msg);
 
 	if (iov != iov_fast)
 		xnfree(iov);
diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
index ed2e13578..29555cb21 100644
--- a/kernel/cobalt/rtdm/fd.c
+++ b/kernel/cobalt/rtdm/fd.c
@@ -31,6 +31,7 @@
 #include <cobalt/kernel/time.h>
 #include <pipeline/inband_work.h>
 #include <trace/events/cobalt-rtdm.h>
+#include <rtdm/compat.h>
 #include <rtdm/fd.h>
 #include "internal.h"
 #include "posix/process.h"
@@ -998,6 +999,127 @@ int rtdm_fd_select(int ufd, struct xnselector *selector,
 	return ret;
 }
 
+int rtdm_fd_get_setsockaddr_args(struct rtdm_fd *fd,
+				 struct _rtdm_setsockaddr_args *dst,
+				 const void *src)
+{
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+	if (rtdm_fd_is_compat(fd)) {
+		struct compat_rtdm_setsockaddr_args cargs;
+		int ret;
+
+		if (!rtdm_read_user_ok(fd, src, sizeof(cargs)))
+			return -EFAULT;
+
+		ret = rtdm_copy_from_user(fd, &cargs, src, sizeof(cargs));
+		if (ret)
+			return ret;
+
+		dst->addr = compat_ptr(cargs.addr);
+		dst->addrlen = cargs.addrlen;
+
+		return 0;
+	}
+#endif
+
+	if (!rtdm_read_user_ok(fd, src, sizeof(*dst)))
+		return -EFAULT;
+
+	return rtdm_copy_from_user(fd, dst, src, sizeof(*dst));
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_get_setsockaddr_args);
+
+int rtdm_fd_get_setsockopt_args(struct rtdm_fd *fd,
+				struct _rtdm_setsockopt_args *dst,
+				const void *src)
+{
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+	if (rtdm_fd_is_compat(fd)) {
+		struct compat_rtdm_setsockopt_args cargs;
+		int ret;
+
+		if (!rtdm_read_user_ok(fd, src, sizeof(cargs)))
+			return -EFAULT;
+
+		ret = rtdm_copy_from_user(fd, &cargs, src, sizeof(cargs));
+		if (ret)
+			return ret;
+
+		dst->optlen = cargs.optlen;
+		dst->optval = compat_ptr(cargs.optval);
+		dst->optname = cargs.optname;
+		dst->level = cargs.level;
+
+		return 0;
+	}
+#endif
+
+	if (!rtdm_read_user_ok(fd, src, sizeof(*dst)))
+		return -EFAULT;
+
+	return rtdm_copy_from_user(fd, dst, src, sizeof(*dst));
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_get_setsockopt_args);
+
+int rtdm_fd_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
+		      const struct user_msghdr *msg, bool rw)
+{
+	size_t sz;
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+	sz = rtdm_fd_is_compat(fd) ? sizeof(struct compat_iovec) : sizeof(*iov);
+#else
+	sz = sizeof(*iov);
+#endif
+
+	sz *= msg->msg_iovlen;
+
+	if (!rw && !rtdm_read_user_ok(fd, msg->msg_iov, sz))
+		return -EFAULT;
+
+	if (rw && !rtdm_rw_user_ok(fd, msg->msg_iov, sz))
+		return -EFAULT;
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+	if (rtdm_fd_is_compat(fd))
+		return sys32_get_iovec(
+			iov, (struct compat_iovec __user *)msg->msg_iov,
+			(int)msg->msg_iovlen);
+#endif
+
+	return rtdm_copy_from_user(fd, iov, msg->msg_iov, sz);
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_get_iovec);
+
+int rtdm_fd_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
+		      const struct user_msghdr *msg)
+{
+	size_t sz;
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+	sz = rtdm_fd_is_compat(fd) ? sizeof(struct compat_iovec) : sizeof(*iov);
+#else
+	sz = sizeof(*iov);
+#endif
+
+	sz *= msg->msg_iovlen;
+
+	if (!rtdm_rw_user_ok(fd, msg->msg_iov, sz))
+		return -EFAULT;
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+	if (rtdm_fd_is_compat(fd))
+		return sys32_put_iovec(
+			(struct compat_iovec __user *)msg->msg_iov, iov,
+			(int)msg->msg_iovlen);
+#endif
+
+	return rtdm_copy_to_user(fd, msg->msg_iov, iov, sz);
+}
+EXPORT_SYMBOL_GPL(rtdm_fd_put_iovec);
+
 static void destroy_fd(void *cookie, struct xnid *id)
 {
 	struct cobalt_ppd *p = cookie;
diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
index dffc6e837..92b7617fb 100644
--- a/kernel/drivers/can/rtcan_raw.c
+++ b/kernel/drivers/can/rtcan_raw.c
@@ -41,6 +41,7 @@
 #include <rtdm/driver.h>
 
 #include <rtdm/can.h>
+#include <rtdm/compat.h>
 #include "rtcan_version.h"
 #include "rtcan_socket.h"
 #include "rtcan_list.h"
@@ -411,17 +412,15 @@ int rtcan_raw_ioctl(struct rtdm_fd *fd,
     int ret = 0;
 
     switch (request) {
-    case _RTIOC_BIND: {
+    COMPAT_CASE(_RTIOC_BIND): {
+
 	struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
 	struct sockaddr_can *sockaddr, sockaddr_buf;
 
 	if (rtdm_fd_is_user(fd)) {
-	    /* Copy argument structure from userspace */
-	    if (!rtdm_read_user_ok(fd, arg,
-				   sizeof(struct _rtdm_setsockaddr_args)) ||
-		rtdm_copy_from_user(fd, &setaddr_buf, arg,
-				    sizeof(struct _rtdm_setsockaddr_args)))
-		return -EFAULT;
+	    ret = rtdm_fd_get_setsockaddr_args(fd, &setaddr_buf, arg);
+	    if (ret)
+		return ret;
 
 	    setaddr = &setaddr_buf;
 
@@ -447,16 +446,14 @@ int rtcan_raw_ioctl(struct rtdm_fd *fd,
 	break;
     }
 
-    case _RTIOC_SETSOCKOPT: {
+    COMPAT_CASE(_RTIOC_SETSOCKOPT): {
 	struct _rtdm_setsockopt_args *setopt;
 	struct _rtdm_setsockopt_args setopt_buf;
 
 	if (rtdm_fd_is_user(fd)) {
-	    if (!rtdm_read_user_ok(fd, arg,
-				   sizeof(struct _rtdm_setsockopt_args)) ||
-		rtdm_copy_from_user(fd, &setopt_buf, arg,
-				    sizeof(struct _rtdm_setsockopt_args)))
-		return -EFAULT;
+	    ret = rtdm_fd_get_setsockopt_args(fd, &setopt_buf, arg);
+	    if (ret)
+		    return ret;
 
 	    setopt = &setopt_buf;
 	} else
@@ -575,11 +572,9 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
 
     if (rtdm_fd_is_user(fd)) {
 	/* Copy IO vector from userspace */
-	if (!rtdm_rw_user_ok(fd, msg->msg_iov,
-			     sizeof(struct iovec)) ||
-	    rtdm_copy_from_user(fd, &iov_buf, msg->msg_iov,
-				sizeof(struct iovec)))
-	    return -EFAULT;
+	ret = rtdm_fd_get_iovec(fd, &iov_buf, msg, true);
+	if (ret)
+		return -EFAULT;
 
 	iov = &iov_buf;
     }
@@ -716,9 +711,9 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
 	iov->iov_base += sizeof(can_frame_t);
 	iov->iov_len -= sizeof(can_frame_t);
 	/* ... and copy it, too. */
-	if (rtdm_copy_to_user(fd, msg->msg_iov, iov,
-			      sizeof(struct iovec)))
-	    return -EFAULT;
+	ret = rtdm_fd_put_iovec(fd, iov, msg);
+	if (ret)
+		return -EFAULT;
 
 	/* Copy timestamp if existent and wanted */
 	if (msg->msg_controllen) {
@@ -922,10 +917,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
     if (rtdm_fd_is_user(fd)) {
 
 	/* Copy IO vector from userspace */
-	if (!rtdm_rw_user_ok(fd, msg->msg_iov,
-			     sizeof(struct iovec)) ||
-	    rtdm_copy_from_user(fd, &iov_buf, msg->msg_iov,
-				sizeof(struct iovec))) {
+	if (rtdm_fd_get_iovec(fd, &iov_buf, msg, false)) {
 	    ret = -EFAULT;
 	    goto finally;
 	}
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/3] drivers/net/stack/ipv4/udp/udp.c: Add compat support
  2022-08-18  7:14 [PATCH 0/3] Enablement of compat tests in CI Florian Bezdeka
  2022-08-18  7:14 ` [PATCH 1/3] rtnet: Enable compat ioctl interface Florian Bezdeka
  2022-08-18  7:14 ` [PATCH 2/3] drivers/rtcan: Implement compat support for the rtcan driver Florian Bezdeka
@ 2022-08-18  7:14 ` Florian Bezdeka
  2 siblings, 0 replies; 8+ messages in thread
From: Florian Bezdeka @ 2022-08-18  7:14 UTC (permalink / raw)
  To: xenomai; +Cc: jan.kiszka, Florian Bezdeka, Konstantin Smola

The rtnet interface was lacking compat support for the following ioctl
commands:
  - _RTIOC_BIND
  - _RTIOC_CONNECT

This patch is heavily inspired by Konstantin's proposal but migrated
to some rtnet APIs that allow us to stay away from
  #ifdef CONFIG_XENO_ARCH_SYS3264
sections.

Reported-by: Konstantin Smola <ksmola51@gmail.com>
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
 kernel/drivers/net/stack/ipv4/udp/udp.c | 29 ++++++++++++++-----------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c
index 5977a3bc2..777c8a27a 100644
--- a/kernel/drivers/net/stack/ipv4/udp/udp.c
+++ b/kernel/drivers/net/stack/ipv4/udp/udp.c
@@ -31,6 +31,7 @@
 #include <linux/tcp.h>
 #include <linux/list.h>
 
+#include <rtdm/compat.h>
 #include <rtskb.h>
 #include <rtnet_internal.h>
 #include <rtnet_checksum.h>
@@ -355,25 +356,27 @@ void rt_udp_close(struct rtdm_fd *fd)
 int rt_udp_ioctl(struct rtdm_fd *fd, unsigned int request, void __user *arg)
 {
 	struct rtsocket *sock = rtdm_fd_to_private(fd);
-	const struct _rtdm_setsockaddr_args *setaddr;
-	struct _rtdm_setsockaddr_args _setaddr;
+	struct _rtdm_setsockaddr_args args;
+	bool do_bind = false;
+	int ret;
 
 	/* fast path for common socket IOCTLs */
 	if (_IOC_TYPE(request) == RTIOC_TYPE_NETWORK)
 		return rt_socket_common_ioctl(fd, request, arg);
 
 	switch (request) {
-	case _RTIOC_BIND:
-	case _RTIOC_CONNECT:
-		setaddr = rtnet_get_arg(fd, &_setaddr, arg, sizeof(_setaddr));
-		if (IS_ERR(setaddr))
-			return PTR_ERR(setaddr);
-		if (request == _RTIOC_BIND)
-			return rt_udp_bind(fd, sock, setaddr->addr,
-					   setaddr->addrlen);
-
-		return rt_udp_connect(fd, sock, setaddr->addr,
-				      setaddr->addrlen);
+	COMPAT_CASE(_RTIOC_BIND):
+		do_bind = true;
+		fallthrough;
+	COMPAT_CASE(_RTIOC_CONNECT):
+		ret = rtdm_fd_get_setsockaddr_args(fd, &args, arg);
+		if (ret)
+			return ret;
+
+		if (do_bind)
+			return rt_udp_bind(fd, sock, args.addr, args.addrlen);
+
+		return rt_udp_connect(fd, sock, args.addr, args.addrlen);
 
 	default:
 		return rt_ip_ioctl(fd, request, arg);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3] drivers/rtcan: Implement compat support for the rtcan driver
  2022-08-18  7:14 ` [PATCH 2/3] drivers/rtcan: Implement compat support for the rtcan driver Florian Bezdeka
@ 2022-09-05 11:44   ` Jan Kiszka
  2022-09-05 11:49     ` Jan Kiszka
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Kiszka @ 2022-09-05 11:44 UTC (permalink / raw)
  To: Florian Bezdeka, xenomai

On 18.08.22 09:14, Florian Bezdeka wrote:
> Once Xenomai was running as compat application (=32bit applicaiton over
> 64bit kernel) the can smokey test failed. This patch fixes the test by
> implementing the necessary compat bits.
> 
> Affected ioctls:
>   - _RTIOC_BIND
>   - _RTIOC_SETSOCKOPT
> 
> Affected syscalls:
>   - recvmsg
>   - sendmsg
> 
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> ---
>  include/cobalt/kernel/rtdm/fd.h |  16 +++++
>  kernel/cobalt/rtdm/drvlib.c     |  17 +----
>  kernel/cobalt/rtdm/fd.c         | 122 ++++++++++++++++++++++++++++++++

Can you factor out the RTDM extensions into a separate commit? Deserves
to be argued over on its own.

And can those helpers then be used also be RTnet?

Jan

>  kernel/drivers/can/rtcan_raw.c  |  42 +++++------
>  4 files changed, 157 insertions(+), 40 deletions(-)
> 
> diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
> index 058a9c638..176c67e22 100644
> --- a/include/cobalt/kernel/rtdm/fd.h
> +++ b/include/cobalt/kernel/rtdm/fd.h
> @@ -29,6 +29,8 @@
>  struct vm_area_struct;
>  struct rtdm_fd;
>  struct _rtdm_mmap_request;
> +struct _rtdm_setsockaddr_args;
> +struct _rtdm_setsockopt_args;
>  struct xnselector;
>  struct cobalt_ppd;
>  struct rtdm_device;
> @@ -403,6 +405,20 @@ int rtdm_fd_valid_p(int ufd);
>  int rtdm_fd_select(int ufd, struct xnselector *selector,
>  		   unsigned int type);
>  
> +int rtdm_fd_get_setsockaddr_args(struct rtdm_fd *fd,
> +				 struct _rtdm_setsockaddr_args *dst,
> +				 const void *src);
> +
> +int rtdm_fd_get_setsockopt_args(struct rtdm_fd *fd,
> +				struct _rtdm_setsockopt_args *dst,
> +				const void *src);
> +
> +int rtdm_fd_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
> +		      const struct user_msghdr *msg, bool rw);
> +
> +int rtdm_fd_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
> +		      const struct user_msghdr *msg);
> +
>  int rtdm_device_new_fd(struct rtdm_fd *fd, int ufd,
>  		struct rtdm_device *dev);
>  
> diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
> index 4eaf3a57c..30455c3d7 100644
> --- a/kernel/cobalt/rtdm/drvlib.c
> +++ b/kernel/cobalt/rtdm/drvlib.c
> @@ -2211,14 +2211,7 @@ int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
>  		return 0;
>  	}
>  
> -#ifdef CONFIG_XENO_ARCH_SYS3264
> -	if (rtdm_fd_is_compat(fd))
> -		return sys32_get_iovec(iov,
> -			       (struct compat_iovec __user *)msg->msg_iov,
> -			       msg->msg_iovlen);
> -#endif
> -
> -	return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
> +	return rtdm_fd_get_iovec(fd, iov, msg, false);
>  }
>  EXPORT_SYMBOL_GPL(rtdm_get_iovec);
>  
> @@ -2233,13 +2226,7 @@ int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
>  		memcpy(msg->msg_iov, iov, len);
>  		ret = 0;
>  	} else
> -#ifdef CONFIG_XENO_ARCH_SYS3264
> -		if (rtdm_fd_is_compat(fd))
> -			ret = sys32_put_iovec((struct compat_iovec __user *)msg->msg_iov,
> -					      iov, msg->msg_iovlen);
> -		else
> -#endif
> -			ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
> +		ret = rtdm_fd_put_iovec(fd, iov, msg);
>  
>  	if (iov != iov_fast)
>  		xnfree(iov);
> diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
> index ed2e13578..29555cb21 100644
> --- a/kernel/cobalt/rtdm/fd.c
> +++ b/kernel/cobalt/rtdm/fd.c
> @@ -31,6 +31,7 @@
>  #include <cobalt/kernel/time.h>
>  #include <pipeline/inband_work.h>
>  #include <trace/events/cobalt-rtdm.h>
> +#include <rtdm/compat.h>
>  #include <rtdm/fd.h>
>  #include "internal.h"
>  #include "posix/process.h"
> @@ -998,6 +999,127 @@ int rtdm_fd_select(int ufd, struct xnselector *selector,
>  	return ret;
>  }
>  
> +int rtdm_fd_get_setsockaddr_args(struct rtdm_fd *fd,
> +				 struct _rtdm_setsockaddr_args *dst,
> +				 const void *src)
> +{
> +
> +#ifdef CONFIG_XENO_ARCH_SYS3264
> +	if (rtdm_fd_is_compat(fd)) {
> +		struct compat_rtdm_setsockaddr_args cargs;
> +		int ret;
> +
> +		if (!rtdm_read_user_ok(fd, src, sizeof(cargs)))
> +			return -EFAULT;
> +
> +		ret = rtdm_copy_from_user(fd, &cargs, src, sizeof(cargs));
> +		if (ret)
> +			return ret;
> +
> +		dst->addr = compat_ptr(cargs.addr);
> +		dst->addrlen = cargs.addrlen;
> +
> +		return 0;
> +	}
> +#endif
> +
> +	if (!rtdm_read_user_ok(fd, src, sizeof(*dst)))
> +		return -EFAULT;
> +
> +	return rtdm_copy_from_user(fd, dst, src, sizeof(*dst));
> +}
> +EXPORT_SYMBOL_GPL(rtdm_fd_get_setsockaddr_args);
> +
> +int rtdm_fd_get_setsockopt_args(struct rtdm_fd *fd,
> +				struct _rtdm_setsockopt_args *dst,
> +				const void *src)
> +{
> +
> +#ifdef CONFIG_XENO_ARCH_SYS3264
> +	if (rtdm_fd_is_compat(fd)) {
> +		struct compat_rtdm_setsockopt_args cargs;
> +		int ret;
> +
> +		if (!rtdm_read_user_ok(fd, src, sizeof(cargs)))
> +			return -EFAULT;
> +
> +		ret = rtdm_copy_from_user(fd, &cargs, src, sizeof(cargs));
> +		if (ret)
> +			return ret;
> +
> +		dst->optlen = cargs.optlen;
> +		dst->optval = compat_ptr(cargs.optval);
> +		dst->optname = cargs.optname;
> +		dst->level = cargs.level;
> +
> +		return 0;
> +	}
> +#endif
> +
> +	if (!rtdm_read_user_ok(fd, src, sizeof(*dst)))
> +		return -EFAULT;
> +
> +	return rtdm_copy_from_user(fd, dst, src, sizeof(*dst));
> +}
> +EXPORT_SYMBOL_GPL(rtdm_fd_get_setsockopt_args);
> +
> +int rtdm_fd_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
> +		      const struct user_msghdr *msg, bool rw)
> +{
> +	size_t sz;
> +
> +#ifdef CONFIG_XENO_ARCH_SYS3264
> +	sz = rtdm_fd_is_compat(fd) ? sizeof(struct compat_iovec) : sizeof(*iov);
> +#else
> +	sz = sizeof(*iov);
> +#endif
> +
> +	sz *= msg->msg_iovlen;
> +
> +	if (!rw && !rtdm_read_user_ok(fd, msg->msg_iov, sz))
> +		return -EFAULT;
> +
> +	if (rw && !rtdm_rw_user_ok(fd, msg->msg_iov, sz))
> +		return -EFAULT;
> +
> +#ifdef CONFIG_XENO_ARCH_SYS3264
> +	if (rtdm_fd_is_compat(fd))
> +		return sys32_get_iovec(
> +			iov, (struct compat_iovec __user *)msg->msg_iov,
> +			(int)msg->msg_iovlen);
> +#endif
> +
> +	return rtdm_copy_from_user(fd, iov, msg->msg_iov, sz);
> +}
> +EXPORT_SYMBOL_GPL(rtdm_fd_get_iovec);
> +
> +int rtdm_fd_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
> +		      const struct user_msghdr *msg)
> +{
> +	size_t sz;
> +
> +#ifdef CONFIG_XENO_ARCH_SYS3264
> +	sz = rtdm_fd_is_compat(fd) ? sizeof(struct compat_iovec) : sizeof(*iov);
> +#else
> +	sz = sizeof(*iov);
> +#endif
> +
> +	sz *= msg->msg_iovlen;
> +
> +	if (!rtdm_rw_user_ok(fd, msg->msg_iov, sz))
> +		return -EFAULT;
> +
> +#ifdef CONFIG_XENO_ARCH_SYS3264
> +	if (rtdm_fd_is_compat(fd))
> +		return sys32_put_iovec(
> +			(struct compat_iovec __user *)msg->msg_iov, iov,
> +			(int)msg->msg_iovlen);
> +#endif
> +
> +	return rtdm_copy_to_user(fd, msg->msg_iov, iov, sz);
> +}
> +EXPORT_SYMBOL_GPL(rtdm_fd_put_iovec);
> +
>  static void destroy_fd(void *cookie, struct xnid *id)
>  {
>  	struct cobalt_ppd *p = cookie;
> diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
> index dffc6e837..92b7617fb 100644
> --- a/kernel/drivers/can/rtcan_raw.c
> +++ b/kernel/drivers/can/rtcan_raw.c
> @@ -41,6 +41,7 @@
>  #include <rtdm/driver.h>
>  
>  #include <rtdm/can.h>
> +#include <rtdm/compat.h>
>  #include "rtcan_version.h"
>  #include "rtcan_socket.h"
>  #include "rtcan_list.h"
> @@ -411,17 +412,15 @@ int rtcan_raw_ioctl(struct rtdm_fd *fd,
>      int ret = 0;
>  
>      switch (request) {
> -    case _RTIOC_BIND: {
> +    COMPAT_CASE(_RTIOC_BIND): {
> +
>  	struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
>  	struct sockaddr_can *sockaddr, sockaddr_buf;
>  
>  	if (rtdm_fd_is_user(fd)) {
> -	    /* Copy argument structure from userspace */
> -	    if (!rtdm_read_user_ok(fd, arg,
> -				   sizeof(struct _rtdm_setsockaddr_args)) ||
> -		rtdm_copy_from_user(fd, &setaddr_buf, arg,
> -				    sizeof(struct _rtdm_setsockaddr_args)))
> -		return -EFAULT;
> +	    ret = rtdm_fd_get_setsockaddr_args(fd, &setaddr_buf, arg);
> +	    if (ret)
> +		return ret;
>  
>  	    setaddr = &setaddr_buf;
>  
> @@ -447,16 +446,14 @@ int rtcan_raw_ioctl(struct rtdm_fd *fd,
>  	break;
>      }
>  
> -    case _RTIOC_SETSOCKOPT: {
> +    COMPAT_CASE(_RTIOC_SETSOCKOPT): {
>  	struct _rtdm_setsockopt_args *setopt;
>  	struct _rtdm_setsockopt_args setopt_buf;
>  
>  	if (rtdm_fd_is_user(fd)) {
> -	    if (!rtdm_read_user_ok(fd, arg,
> -				   sizeof(struct _rtdm_setsockopt_args)) ||
> -		rtdm_copy_from_user(fd, &setopt_buf, arg,
> -				    sizeof(struct _rtdm_setsockopt_args)))
> -		return -EFAULT;
> +	    ret = rtdm_fd_get_setsockopt_args(fd, &setopt_buf, arg);
> +	    if (ret)
> +		    return ret;
>  
>  	    setopt = &setopt_buf;
>  	} else
> @@ -575,11 +572,9 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
>  
>      if (rtdm_fd_is_user(fd)) {
>  	/* Copy IO vector from userspace */
> -	if (!rtdm_rw_user_ok(fd, msg->msg_iov,
> -			     sizeof(struct iovec)) ||
> -	    rtdm_copy_from_user(fd, &iov_buf, msg->msg_iov,
> -				sizeof(struct iovec)))
> -	    return -EFAULT;
> +	ret = rtdm_fd_get_iovec(fd, &iov_buf, msg, true);
> +	if (ret)
> +		return -EFAULT;
>  
>  	iov = &iov_buf;
>      }
> @@ -716,9 +711,9 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
>  	iov->iov_base += sizeof(can_frame_t);
>  	iov->iov_len -= sizeof(can_frame_t);
>  	/* ... and copy it, too. */
> -	if (rtdm_copy_to_user(fd, msg->msg_iov, iov,
> -			      sizeof(struct iovec)))
> -	    return -EFAULT;
> +	ret = rtdm_fd_put_iovec(fd, iov, msg);
> +	if (ret)
> +		return -EFAULT;
>  
>  	/* Copy timestamp if existent and wanted */
>  	if (msg->msg_controllen) {
> @@ -922,10 +917,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
>      if (rtdm_fd_is_user(fd)) {
>  
>  	/* Copy IO vector from userspace */
> -	if (!rtdm_rw_user_ok(fd, msg->msg_iov,
> -			     sizeof(struct iovec)) ||
> -	    rtdm_copy_from_user(fd, &iov_buf, msg->msg_iov,
> -				sizeof(struct iovec))) {
> +	if (rtdm_fd_get_iovec(fd, &iov_buf, msg, false)) {
>  	    ret = -EFAULT;
>  	    goto finally;
>  	}

-- 
Siemens AG, Technology
Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3] drivers/rtcan: Implement compat support for the rtcan driver
  2022-09-05 11:44   ` Jan Kiszka
@ 2022-09-05 11:49     ` Jan Kiszka
  2022-09-15 13:11       ` Bezdeka, Florian
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Kiszka @ 2022-09-05 11:49 UTC (permalink / raw)
  To: Florian Bezdeka, xenomai

On 05.09.22 13:44, Jan Kiszka wrote:
> On 18.08.22 09:14, Florian Bezdeka wrote:
>> Once Xenomai was running as compat application (=32bit applicaiton over
>> 64bit kernel) the can smokey test failed. This patch fixes the test by
>> implementing the necessary compat bits.
>>
>> Affected ioctls:
>>   - _RTIOC_BIND
>>   - _RTIOC_SETSOCKOPT
>>
>> Affected syscalls:
>>   - recvmsg
>>   - sendmsg
>>
>> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
>> ---
>>  include/cobalt/kernel/rtdm/fd.h |  16 +++++
>>  kernel/cobalt/rtdm/drvlib.c     |  17 +----
>>  kernel/cobalt/rtdm/fd.c         | 122 ++++++++++++++++++++++++++++++++
> 
> Can you factor out the RTDM extensions into a separate commit? Deserves
> to be argued over on its own.
> 
> And can those helpers then be used also be RTnet?

Ah, they are, but only partially. Why not the others? And what about the
IPC drivers?

Jan

> 
> Jan
> 
>>  kernel/drivers/can/rtcan_raw.c  |  42 +++++------
>>  4 files changed, 157 insertions(+), 40 deletions(-)
>>
>> diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
>> index 058a9c638..176c67e22 100644
>> --- a/include/cobalt/kernel/rtdm/fd.h
>> +++ b/include/cobalt/kernel/rtdm/fd.h
>> @@ -29,6 +29,8 @@
>>  struct vm_area_struct;
>>  struct rtdm_fd;
>>  struct _rtdm_mmap_request;
>> +struct _rtdm_setsockaddr_args;
>> +struct _rtdm_setsockopt_args;
>>  struct xnselector;
>>  struct cobalt_ppd;
>>  struct rtdm_device;
>> @@ -403,6 +405,20 @@ int rtdm_fd_valid_p(int ufd);
>>  int rtdm_fd_select(int ufd, struct xnselector *selector,
>>  		   unsigned int type);
>>  
>> +int rtdm_fd_get_setsockaddr_args(struct rtdm_fd *fd,
>> +				 struct _rtdm_setsockaddr_args *dst,
>> +				 const void *src);
>> +
>> +int rtdm_fd_get_setsockopt_args(struct rtdm_fd *fd,
>> +				struct _rtdm_setsockopt_args *dst,
>> +				const void *src);
>> +
>> +int rtdm_fd_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
>> +		      const struct user_msghdr *msg, bool rw);
>> +
>> +int rtdm_fd_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
>> +		      const struct user_msghdr *msg);
>> +
>>  int rtdm_device_new_fd(struct rtdm_fd *fd, int ufd,
>>  		struct rtdm_device *dev);
>>  
>> diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
>> index 4eaf3a57c..30455c3d7 100644
>> --- a/kernel/cobalt/rtdm/drvlib.c
>> +++ b/kernel/cobalt/rtdm/drvlib.c
>> @@ -2211,14 +2211,7 @@ int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
>>  		return 0;
>>  	}
>>  
>> -#ifdef CONFIG_XENO_ARCH_SYS3264
>> -	if (rtdm_fd_is_compat(fd))
>> -		return sys32_get_iovec(iov,
>> -			       (struct compat_iovec __user *)msg->msg_iov,
>> -			       msg->msg_iovlen);
>> -#endif
>> -
>> -	return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
>> +	return rtdm_fd_get_iovec(fd, iov, msg, false);
>>  }
>>  EXPORT_SYMBOL_GPL(rtdm_get_iovec);
>>  
>> @@ -2233,13 +2226,7 @@ int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
>>  		memcpy(msg->msg_iov, iov, len);
>>  		ret = 0;
>>  	} else
>> -#ifdef CONFIG_XENO_ARCH_SYS3264
>> -		if (rtdm_fd_is_compat(fd))
>> -			ret = sys32_put_iovec((struct compat_iovec __user *)msg->msg_iov,
>> -					      iov, msg->msg_iovlen);
>> -		else
>> -#endif
>> -			ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
>> +		ret = rtdm_fd_put_iovec(fd, iov, msg);
>>  
>>  	if (iov != iov_fast)
>>  		xnfree(iov);
>> diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
>> index ed2e13578..29555cb21 100644
>> --- a/kernel/cobalt/rtdm/fd.c
>> +++ b/kernel/cobalt/rtdm/fd.c
>> @@ -31,6 +31,7 @@
>>  #include <cobalt/kernel/time.h>
>>  #include <pipeline/inband_work.h>
>>  #include <trace/events/cobalt-rtdm.h>
>> +#include <rtdm/compat.h>
>>  #include <rtdm/fd.h>
>>  #include "internal.h"
>>  #include "posix/process.h"
>> @@ -998,6 +999,127 @@ int rtdm_fd_select(int ufd, struct xnselector *selector,
>>  	return ret;
>>  }
>>  
>> +int rtdm_fd_get_setsockaddr_args(struct rtdm_fd *fd,
>> +				 struct _rtdm_setsockaddr_args *dst,
>> +				 const void *src)
>> +{
>> +
>> +#ifdef CONFIG_XENO_ARCH_SYS3264
>> +	if (rtdm_fd_is_compat(fd)) {
>> +		struct compat_rtdm_setsockaddr_args cargs;
>> +		int ret;
>> +
>> +		if (!rtdm_read_user_ok(fd, src, sizeof(cargs)))
>> +			return -EFAULT;
>> +
>> +		ret = rtdm_copy_from_user(fd, &cargs, src, sizeof(cargs));
>> +		if (ret)
>> +			return ret;
>> +
>> +		dst->addr = compat_ptr(cargs.addr);
>> +		dst->addrlen = cargs.addrlen;
>> +
>> +		return 0;
>> +	}
>> +#endif
>> +
>> +	if (!rtdm_read_user_ok(fd, src, sizeof(*dst)))
>> +		return -EFAULT;
>> +
>> +	return rtdm_copy_from_user(fd, dst, src, sizeof(*dst));
>> +}
>> +EXPORT_SYMBOL_GPL(rtdm_fd_get_setsockaddr_args);
>> +
>> +int rtdm_fd_get_setsockopt_args(struct rtdm_fd *fd,
>> +				struct _rtdm_setsockopt_args *dst,
>> +				const void *src)
>> +{
>> +
>> +#ifdef CONFIG_XENO_ARCH_SYS3264
>> +	if (rtdm_fd_is_compat(fd)) {
>> +		struct compat_rtdm_setsockopt_args cargs;
>> +		int ret;
>> +
>> +		if (!rtdm_read_user_ok(fd, src, sizeof(cargs)))
>> +			return -EFAULT;
>> +
>> +		ret = rtdm_copy_from_user(fd, &cargs, src, sizeof(cargs));
>> +		if (ret)
>> +			return ret;
>> +
>> +		dst->optlen = cargs.optlen;
>> +		dst->optval = compat_ptr(cargs.optval);
>> +		dst->optname = cargs.optname;
>> +		dst->level = cargs.level;
>> +
>> +		return 0;
>> +	}
>> +#endif
>> +
>> +	if (!rtdm_read_user_ok(fd, src, sizeof(*dst)))
>> +		return -EFAULT;
>> +
>> +	return rtdm_copy_from_user(fd, dst, src, sizeof(*dst));
>> +}
>> +EXPORT_SYMBOL_GPL(rtdm_fd_get_setsockopt_args);
>> +
>> +int rtdm_fd_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
>> +		      const struct user_msghdr *msg, bool rw)
>> +{
>> +	size_t sz;
>> +
>> +#ifdef CONFIG_XENO_ARCH_SYS3264
>> +	sz = rtdm_fd_is_compat(fd) ? sizeof(struct compat_iovec) : sizeof(*iov);
>> +#else
>> +	sz = sizeof(*iov);
>> +#endif
>> +
>> +	sz *= msg->msg_iovlen;
>> +
>> +	if (!rw && !rtdm_read_user_ok(fd, msg->msg_iov, sz))
>> +		return -EFAULT;
>> +
>> +	if (rw && !rtdm_rw_user_ok(fd, msg->msg_iov, sz))
>> +		return -EFAULT;
>> +
>> +#ifdef CONFIG_XENO_ARCH_SYS3264
>> +	if (rtdm_fd_is_compat(fd))
>> +		return sys32_get_iovec(
>> +			iov, (struct compat_iovec __user *)msg->msg_iov,
>> +			(int)msg->msg_iovlen);
>> +#endif
>> +
>> +	return rtdm_copy_from_user(fd, iov, msg->msg_iov, sz);
>> +}
>> +EXPORT_SYMBOL_GPL(rtdm_fd_get_iovec);
>> +
>> +int rtdm_fd_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
>> +		      const struct user_msghdr *msg)
>> +{
>> +	size_t sz;
>> +
>> +#ifdef CONFIG_XENO_ARCH_SYS3264
>> +	sz = rtdm_fd_is_compat(fd) ? sizeof(struct compat_iovec) : sizeof(*iov);
>> +#else
>> +	sz = sizeof(*iov);
>> +#endif
>> +
>> +	sz *= msg->msg_iovlen;
>> +
>> +	if (!rtdm_rw_user_ok(fd, msg->msg_iov, sz))
>> +		return -EFAULT;
>> +
>> +#ifdef CONFIG_XENO_ARCH_SYS3264
>> +	if (rtdm_fd_is_compat(fd))
>> +		return sys32_put_iovec(
>> +			(struct compat_iovec __user *)msg->msg_iov, iov,
>> +			(int)msg->msg_iovlen);
>> +#endif
>> +
>> +	return rtdm_copy_to_user(fd, msg->msg_iov, iov, sz);
>> +}
>> +EXPORT_SYMBOL_GPL(rtdm_fd_put_iovec);
>> +
>>  static void destroy_fd(void *cookie, struct xnid *id)
>>  {
>>  	struct cobalt_ppd *p = cookie;
>> diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
>> index dffc6e837..92b7617fb 100644
>> --- a/kernel/drivers/can/rtcan_raw.c
>> +++ b/kernel/drivers/can/rtcan_raw.c
>> @@ -41,6 +41,7 @@
>>  #include <rtdm/driver.h>
>>  
>>  #include <rtdm/can.h>
>> +#include <rtdm/compat.h>
>>  #include "rtcan_version.h"
>>  #include "rtcan_socket.h"
>>  #include "rtcan_list.h"
>> @@ -411,17 +412,15 @@ int rtcan_raw_ioctl(struct rtdm_fd *fd,
>>      int ret = 0;
>>  
>>      switch (request) {
>> -    case _RTIOC_BIND: {
>> +    COMPAT_CASE(_RTIOC_BIND): {
>> +
>>  	struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
>>  	struct sockaddr_can *sockaddr, sockaddr_buf;
>>  
>>  	if (rtdm_fd_is_user(fd)) {
>> -	    /* Copy argument structure from userspace */
>> -	    if (!rtdm_read_user_ok(fd, arg,
>> -				   sizeof(struct _rtdm_setsockaddr_args)) ||
>> -		rtdm_copy_from_user(fd, &setaddr_buf, arg,
>> -				    sizeof(struct _rtdm_setsockaddr_args)))
>> -		return -EFAULT;
>> +	    ret = rtdm_fd_get_setsockaddr_args(fd, &setaddr_buf, arg);
>> +	    if (ret)
>> +		return ret;
>>  
>>  	    setaddr = &setaddr_buf;
>>  
>> @@ -447,16 +446,14 @@ int rtcan_raw_ioctl(struct rtdm_fd *fd,
>>  	break;
>>      }
>>  
>> -    case _RTIOC_SETSOCKOPT: {
>> +    COMPAT_CASE(_RTIOC_SETSOCKOPT): {
>>  	struct _rtdm_setsockopt_args *setopt;
>>  	struct _rtdm_setsockopt_args setopt_buf;
>>  
>>  	if (rtdm_fd_is_user(fd)) {
>> -	    if (!rtdm_read_user_ok(fd, arg,
>> -				   sizeof(struct _rtdm_setsockopt_args)) ||
>> -		rtdm_copy_from_user(fd, &setopt_buf, arg,
>> -				    sizeof(struct _rtdm_setsockopt_args)))
>> -		return -EFAULT;
>> +	    ret = rtdm_fd_get_setsockopt_args(fd, &setopt_buf, arg);
>> +	    if (ret)
>> +		    return ret;
>>  
>>  	    setopt = &setopt_buf;
>>  	} else
>> @@ -575,11 +572,9 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
>>  
>>      if (rtdm_fd_is_user(fd)) {
>>  	/* Copy IO vector from userspace */
>> -	if (!rtdm_rw_user_ok(fd, msg->msg_iov,
>> -			     sizeof(struct iovec)) ||
>> -	    rtdm_copy_from_user(fd, &iov_buf, msg->msg_iov,
>> -				sizeof(struct iovec)))
>> -	    return -EFAULT;
>> +	ret = rtdm_fd_get_iovec(fd, &iov_buf, msg, true);
>> +	if (ret)
>> +		return -EFAULT;
>>  
>>  	iov = &iov_buf;
>>      }
>> @@ -716,9 +711,9 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
>>  	iov->iov_base += sizeof(can_frame_t);
>>  	iov->iov_len -= sizeof(can_frame_t);
>>  	/* ... and copy it, too. */
>> -	if (rtdm_copy_to_user(fd, msg->msg_iov, iov,
>> -			      sizeof(struct iovec)))
>> -	    return -EFAULT;
>> +	ret = rtdm_fd_put_iovec(fd, iov, msg);
>> +	if (ret)
>> +		return -EFAULT;
>>  
>>  	/* Copy timestamp if existent and wanted */
>>  	if (msg->msg_controllen) {
>> @@ -922,10 +917,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
>>      if (rtdm_fd_is_user(fd)) {
>>  
>>  	/* Copy IO vector from userspace */
>> -	if (!rtdm_rw_user_ok(fd, msg->msg_iov,
>> -			     sizeof(struct iovec)) ||
>> -	    rtdm_copy_from_user(fd, &iov_buf, msg->msg_iov,
>> -				sizeof(struct iovec))) {
>> +	if (rtdm_fd_get_iovec(fd, &iov_buf, msg, false)) {
>>  	    ret = -EFAULT;
>>  	    goto finally;
>>  	}
> 

-- 
Siemens AG, Technology
Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/3] rtnet: Enable compat ioctl interface
  2022-08-18  7:14 ` [PATCH 1/3] rtnet: Enable compat ioctl interface Florian Bezdeka
@ 2022-09-05 11:49   ` Jan Kiszka
  0 siblings, 0 replies; 8+ messages in thread
From: Jan Kiszka @ 2022-09-05 11:49 UTC (permalink / raw)
  To: Florian Bezdeka, xenomai

On 18.08.22 09:14, Florian Bezdeka wrote:
> Running rtnet for compat applications failed because the compat ioctl
> interface was not activated.
> 
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> ---
>  kernel/drivers/net/stack/rtnet_chrdev.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/kernel/drivers/net/stack/rtnet_chrdev.c b/kernel/drivers/net/stack/rtnet_chrdev.c
> index 9457661a1..fa859c3bc 100644
> --- a/kernel/drivers/net/stack/rtnet_chrdev.c
> +++ b/kernel/drivers/net/stack/rtnet_chrdev.c
> @@ -195,6 +195,7 @@ void rtnet_unregister_ioctls(struct rtnet_ioctls *ioctls)
>  static struct file_operations rtnet_fops = {
>  	.owner = THIS_MODULE,
>  	.unlocked_ioctl = rtnet_ioctl,
> +	.compat_ioctl = rtnet_ioctl,
>  };
>  
>  static struct miscdevice rtnet_chr_misc_dev = {

Applied this one already, thanks.

Jan

-- 
Siemens AG, Technology
Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3] drivers/rtcan: Implement compat support for the rtcan driver
  2022-09-05 11:49     ` Jan Kiszka
@ 2022-09-15 13:11       ` Bezdeka, Florian
  0 siblings, 0 replies; 8+ messages in thread
From: Bezdeka, Florian @ 2022-09-15 13:11 UTC (permalink / raw)
  To: jan.kiszka, xenomai

On Mon, 2022-09-05 at 13:49 +0200, Jan Kiszka wrote:
> On 05.09.22 13:44, Jan Kiszka wrote:
> > On 18.08.22 09:14, Florian Bezdeka wrote:
> > > Once Xenomai was running as compat application (=32bit applicaiton over
> > > 64bit kernel) the can smokey test failed. This patch fixes the test by
> > > implementing the necessary compat bits.
> > > 
> > > Affected ioctls:
> > >   - _RTIOC_BIND
> > >   - _RTIOC_SETSOCKOPT
> > > 
> > > Affected syscalls:
> > >   - recvmsg
> > >   - sendmsg
> > > 
> > > Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> > > ---
> > >  include/cobalt/kernel/rtdm/fd.h |  16 +++++
> > >  kernel/cobalt/rtdm/drvlib.c     |  17 +----
> > >  kernel/cobalt/rtdm/fd.c         | 122 ++++++++++++++++++++++++++++++++
> > 
> > Can you factor out the RTDM extensions into a separate commit? Deserves
> > to be argued over on its own.
> > 
> > And can those helpers then be used also be RTnet?
> 
> Ah, they are, but only partially. Why not the others? And what about the
> IPC drivers?

I will factor that out. Should have done in v1 already...

I'm following a step-by-step approach right now, fixing failing tests
first, then searching for other affected call-sites. With this series
applied the Xenomai testsuite (smokey) is green again.

We have a list of affected drivers in [1]. Especially the rt_tcp driver
is already on the list. There might be more. Feel free to extend the
list.

[1] https://gitlab.com/Xenomai/xenomai-hacker-space/-/wikis/y2038/Y2038_Affected_Drivers

> 
> Jan
> 
> > 
> > Jan
> > 
> > >  kernel/drivers/can/rtcan_raw.c  |  42 +++++------
> > >  4 files changed, 157 insertions(+), 40 deletions(-)
> > > 
> > > diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
> > > index 058a9c638..176c67e22 100644
> > > --- a/include/cobalt/kernel/rtdm/fd.h
> > > +++ b/include/cobalt/kernel/rtdm/fd.h
> > > @@ -29,6 +29,8 @@
> > >  struct vm_area_struct;
> > >  struct rtdm_fd;
> > >  struct _rtdm_mmap_request;
> > > +struct _rtdm_setsockaddr_args;
> > > +struct _rtdm_setsockopt_args;
> > >  struct xnselector;
> > >  struct cobalt_ppd;
> > >  struct rtdm_device;
> > > @@ -403,6 +405,20 @@ int rtdm_fd_valid_p(int ufd);
> > >  int rtdm_fd_select(int ufd, struct xnselector *selector,
> > >  		   unsigned int type);
> > >  
> > > +int rtdm_fd_get_setsockaddr_args(struct rtdm_fd *fd,
> > > +				 struct _rtdm_setsockaddr_args *dst,
> > > +				 const void *src);
> > > +
> > > +int rtdm_fd_get_setsockopt_args(struct rtdm_fd *fd,
> > > +				struct _rtdm_setsockopt_args *dst,
> > > +				const void *src);
> > > +
> > > +int rtdm_fd_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
> > > +		      const struct user_msghdr *msg, bool rw);
> > > +
> > > +int rtdm_fd_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
> > > +		      const struct user_msghdr *msg);
> > > +
> > >  int rtdm_device_new_fd(struct rtdm_fd *fd, int ufd,
> > >  		struct rtdm_device *dev);
> > >  
> > > diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
> > > index 4eaf3a57c..30455c3d7 100644
> > > --- a/kernel/cobalt/rtdm/drvlib.c
> > > +++ b/kernel/cobalt/rtdm/drvlib.c
> > > @@ -2211,14 +2211,7 @@ int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp,
> > >  		return 0;
> > >  	}
> > >  
> > > -#ifdef CONFIG_XENO_ARCH_SYS3264
> > > -	if (rtdm_fd_is_compat(fd))
> > > -		return sys32_get_iovec(iov,
> > > -			       (struct compat_iovec __user *)msg->msg_iov,
> > > -			       msg->msg_iovlen);
> > > -#endif
> > > -
> > > -	return rtdm_copy_from_user(fd, iov, msg->msg_iov, len);
> > > +	return rtdm_fd_get_iovec(fd, iov, msg, false);
> > >  }
> > >  EXPORT_SYMBOL_GPL(rtdm_get_iovec);
> > >  
> > > @@ -2233,13 +2226,7 @@ int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov,
> > >  		memcpy(msg->msg_iov, iov, len);
> > >  		ret = 0;
> > >  	} else
> > > -#ifdef CONFIG_XENO_ARCH_SYS3264
> > > -		if (rtdm_fd_is_compat(fd))
> > > -			ret = sys32_put_iovec((struct compat_iovec __user *)msg->msg_iov,
> > > -					      iov, msg->msg_iovlen);
> > > -		else
> > > -#endif
> > > -			ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len);
> > > +		ret = rtdm_fd_put_iovec(fd, iov, msg);
> > >  
> > >  	if (iov != iov_fast)
> > >  		xnfree(iov);
> > > diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
> > > index ed2e13578..29555cb21 100644
> > > --- a/kernel/cobalt/rtdm/fd.c
> > > +++ b/kernel/cobalt/rtdm/fd.c
> > > @@ -31,6 +31,7 @@
> > >  #include <cobalt/kernel/time.h>
> > >  #include <pipeline/inband_work.h>
> > >  #include <trace/events/cobalt-rtdm.h>
> > > +#include <rtdm/compat.h>
> > >  #include <rtdm/fd.h>
> > >  #include "internal.h"
> > >  #include "posix/process.h"
> > > @@ -998,6 +999,127 @@ int rtdm_fd_select(int ufd, struct xnselector *selector,
> > >  	return ret;
> > >  }
> > >  
> > > +int rtdm_fd_get_setsockaddr_args(struct rtdm_fd *fd,
> > > +				 struct _rtdm_setsockaddr_args *dst,
> > > +				 const void *src)
> > > +{
> > > +
> > > +#ifdef CONFIG_XENO_ARCH_SYS3264
> > > +	if (rtdm_fd_is_compat(fd)) {
> > > +		struct compat_rtdm_setsockaddr_args cargs;
> > > +		int ret;
> > > +
> > > +		if (!rtdm_read_user_ok(fd, src, sizeof(cargs)))
> > > +			return -EFAULT;
> > > +
> > > +		ret = rtdm_copy_from_user(fd, &cargs, src, sizeof(cargs));
> > > +		if (ret)
> > > +			return ret;
> > > +
> > > +		dst->addr = compat_ptr(cargs.addr);
> > > +		dst->addrlen = cargs.addrlen;
> > > +
> > > +		return 0;
> > > +	}
> > > +#endif
> > > +
> > > +	if (!rtdm_read_user_ok(fd, src, sizeof(*dst)))
> > > +		return -EFAULT;
> > > +
> > > +	return rtdm_copy_from_user(fd, dst, src, sizeof(*dst));
> > > +}
> > > +EXPORT_SYMBOL_GPL(rtdm_fd_get_setsockaddr_args);
> > > +
> > > +int rtdm_fd_get_setsockopt_args(struct rtdm_fd *fd,
> > > +				struct _rtdm_setsockopt_args *dst,
> > > +				const void *src)
> > > +{
> > > +
> > > +#ifdef CONFIG_XENO_ARCH_SYS3264
> > > +	if (rtdm_fd_is_compat(fd)) {
> > > +		struct compat_rtdm_setsockopt_args cargs;
> > > +		int ret;
> > > +
> > > +		if (!rtdm_read_user_ok(fd, src, sizeof(cargs)))
> > > +			return -EFAULT;
> > > +
> > > +		ret = rtdm_copy_from_user(fd, &cargs, src, sizeof(cargs));
> > > +		if (ret)
> > > +			return ret;
> > > +
> > > +		dst->optlen = cargs.optlen;
> > > +		dst->optval = compat_ptr(cargs.optval);
> > > +		dst->optname = cargs.optname;
> > > +		dst->level = cargs.level;
> > > +
> > > +		return 0;
> > > +	}
> > > +#endif
> > > +
> > > +	if (!rtdm_read_user_ok(fd, src, sizeof(*dst)))
> > > +		return -EFAULT;
> > > +
> > > +	return rtdm_copy_from_user(fd, dst, src, sizeof(*dst));
> > > +}
> > > +EXPORT_SYMBOL_GPL(rtdm_fd_get_setsockopt_args);
> > > +
> > > +int rtdm_fd_get_iovec(struct rtdm_fd *fd, struct iovec *iov,
> > > +		      const struct user_msghdr *msg, bool rw)
> > > +{
> > > +	size_t sz;
> > > +
> > > +#ifdef CONFIG_XENO_ARCH_SYS3264
> > > +	sz = rtdm_fd_is_compat(fd) ? sizeof(struct compat_iovec) : sizeof(*iov);
> > > +#else
> > > +	sz = sizeof(*iov);
> > > +#endif
> > > +
> > > +	sz *= msg->msg_iovlen;
> > > +
> > > +	if (!rw && !rtdm_read_user_ok(fd, msg->msg_iov, sz))
> > > +		return -EFAULT;
> > > +
> > > +	if (rw && !rtdm_rw_user_ok(fd, msg->msg_iov, sz))
> > > +		return -EFAULT;
> > > +
> > > +#ifdef CONFIG_XENO_ARCH_SYS3264
> > > +	if (rtdm_fd_is_compat(fd))
> > > +		return sys32_get_iovec(
> > > +			iov, (struct compat_iovec __user *)msg->msg_iov,
> > > +			(int)msg->msg_iovlen);
> > > +#endif
> > > +
> > > +	return rtdm_copy_from_user(fd, iov, msg->msg_iov, sz);
> > > +}
> > > +EXPORT_SYMBOL_GPL(rtdm_fd_get_iovec);
> > > +
> > > +int rtdm_fd_put_iovec(struct rtdm_fd *fd, const struct iovec *iov,
> > > +		      const struct user_msghdr *msg)
> > > +{
> > > +	size_t sz;
> > > +
> > > +#ifdef CONFIG_XENO_ARCH_SYS3264
> > > +	sz = rtdm_fd_is_compat(fd) ? sizeof(struct compat_iovec) : sizeof(*iov);
> > > +#else
> > > +	sz = sizeof(*iov);
> > > +#endif
> > > +
> > > +	sz *= msg->msg_iovlen;
> > > +
> > > +	if (!rtdm_rw_user_ok(fd, msg->msg_iov, sz))
> > > +		return -EFAULT;
> > > +
> > > +#ifdef CONFIG_XENO_ARCH_SYS3264
> > > +	if (rtdm_fd_is_compat(fd))
> > > +		return sys32_put_iovec(
> > > +			(struct compat_iovec __user *)msg->msg_iov, iov,
> > > +			(int)msg->msg_iovlen);
> > > +#endif
> > > +
> > > +	return rtdm_copy_to_user(fd, msg->msg_iov, iov, sz);
> > > +}
> > > +EXPORT_SYMBOL_GPL(rtdm_fd_put_iovec);
> > > +
> > >  static void destroy_fd(void *cookie, struct xnid *id)
> > >  {
> > >  	struct cobalt_ppd *p = cookie;
> > > diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
> > > index dffc6e837..92b7617fb 100644
> > > --- a/kernel/drivers/can/rtcan_raw.c
> > > +++ b/kernel/drivers/can/rtcan_raw.c
> > > @@ -41,6 +41,7 @@
> > >  #include <rtdm/driver.h>
> > >  
> > >  #include <rtdm/can.h>
> > > +#include <rtdm/compat.h>
> > >  #include "rtcan_version.h"
> > >  #include "rtcan_socket.h"
> > >  #include "rtcan_list.h"
> > > @@ -411,17 +412,15 @@ int rtcan_raw_ioctl(struct rtdm_fd *fd,
> > >      int ret = 0;
> > >  
> > >      switch (request) {
> > > -    case _RTIOC_BIND: {
> > > +    COMPAT_CASE(_RTIOC_BIND): {
> > > +
> > >  	struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
> > >  	struct sockaddr_can *sockaddr, sockaddr_buf;
> > >  
> > >  	if (rtdm_fd_is_user(fd)) {
> > > -	    /* Copy argument structure from userspace */
> > > -	    if (!rtdm_read_user_ok(fd, arg,
> > > -				   sizeof(struct _rtdm_setsockaddr_args)) ||
> > > -		rtdm_copy_from_user(fd, &setaddr_buf, arg,
> > > -				    sizeof(struct _rtdm_setsockaddr_args)))
> > > -		return -EFAULT;
> > > +	    ret = rtdm_fd_get_setsockaddr_args(fd, &setaddr_buf, arg);
> > > +	    if (ret)
> > > +		return ret;
> > >  
> > >  	    setaddr = &setaddr_buf;
> > >  
> > > @@ -447,16 +446,14 @@ int rtcan_raw_ioctl(struct rtdm_fd *fd,
> > >  	break;
> > >      }
> > >  
> > > -    case _RTIOC_SETSOCKOPT: {
> > > +    COMPAT_CASE(_RTIOC_SETSOCKOPT): {
> > >  	struct _rtdm_setsockopt_args *setopt;
> > >  	struct _rtdm_setsockopt_args setopt_buf;
> > >  
> > >  	if (rtdm_fd_is_user(fd)) {
> > > -	    if (!rtdm_read_user_ok(fd, arg,
> > > -				   sizeof(struct _rtdm_setsockopt_args)) ||
> > > -		rtdm_copy_from_user(fd, &setopt_buf, arg,
> > > -				    sizeof(struct _rtdm_setsockopt_args)))
> > > -		return -EFAULT;
> > > +	    ret = rtdm_fd_get_setsockopt_args(fd, &setopt_buf, arg);
> > > +	    if (ret)
> > > +		    return ret;
> > >  
> > >  	    setopt = &setopt_buf;
> > >  	} else
> > > @@ -575,11 +572,9 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
> > >  
> > >      if (rtdm_fd_is_user(fd)) {
> > >  	/* Copy IO vector from userspace */
> > > -	if (!rtdm_rw_user_ok(fd, msg->msg_iov,
> > > -			     sizeof(struct iovec)) ||
> > > -	    rtdm_copy_from_user(fd, &iov_buf, msg->msg_iov,
> > > -				sizeof(struct iovec)))
> > > -	    return -EFAULT;
> > > +	ret = rtdm_fd_get_iovec(fd, &iov_buf, msg, true);
> > > +	if (ret)
> > > +		return -EFAULT;
> > >  
> > >  	iov = &iov_buf;
> > >      }
> > > @@ -716,9 +711,9 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
> > >  	iov->iov_base += sizeof(can_frame_t);
> > >  	iov->iov_len -= sizeof(can_frame_t);
> > >  	/* ... and copy it, too. */
> > > -	if (rtdm_copy_to_user(fd, msg->msg_iov, iov,
> > > -			      sizeof(struct iovec)))
> > > -	    return -EFAULT;
> > > +	ret = rtdm_fd_put_iovec(fd, iov, msg);
> > > +	if (ret)
> > > +		return -EFAULT;
> > >  
> > >  	/* Copy timestamp if existent and wanted */
> > >  	if (msg->msg_controllen) {
> > > @@ -922,10 +917,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
> > >      if (rtdm_fd_is_user(fd)) {
> > >  
> > >  	/* Copy IO vector from userspace */
> > > -	if (!rtdm_rw_user_ok(fd, msg->msg_iov,
> > > -			     sizeof(struct iovec)) ||
> > > -	    rtdm_copy_from_user(fd, &iov_buf, msg->msg_iov,
> > > -				sizeof(struct iovec))) {
> > > +	if (rtdm_fd_get_iovec(fd, &iov_buf, msg, false)) {
> > >  	    ret = -EFAULT;
> > >  	    goto finally;
> > >  	}
> > 
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-09-15 13:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-18  7:14 [PATCH 0/3] Enablement of compat tests in CI Florian Bezdeka
2022-08-18  7:14 ` [PATCH 1/3] rtnet: Enable compat ioctl interface Florian Bezdeka
2022-09-05 11:49   ` Jan Kiszka
2022-08-18  7:14 ` [PATCH 2/3] drivers/rtcan: Implement compat support for the rtcan driver Florian Bezdeka
2022-09-05 11:44   ` Jan Kiszka
2022-09-05 11:49     ` Jan Kiszka
2022-09-15 13:11       ` Bezdeka, Florian
2022-08-18  7:14 ` [PATCH 3/3] drivers/net/stack/ipv4/udp/udp.c: Add compat support Florian Bezdeka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.