Module: xenomai-3
Branch: master
Commit: d8c9e4ec89151d625acaef8abd926a22d48f6a2a
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=d8c9e4ec89151d625acaef8abd926a22d48f6a2a

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Oct 28 17:02:25 2014 +0100

cobalt/posix/compat: fix mq_timedreceive() for 32/64bit neutrality

---

 kernel/cobalt/posix/mqueue.c    |   30 +++++++++++++++---------------
 kernel/cobalt/posix/mqueue.h    |    2 +-
 kernel/cobalt/posix/syscall32.c |    8 +++++---
 3 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index f5a69f9..33d8310 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -998,7 +998,7 @@ COBALT_SYSCALL(mq_timedsend, primary,
 }
 
 int __cobalt_mq_timedreceive(mqd_t uqd, void __user *u_buf,
-                            ssize_t __user *u_len,
+                            ssize_t *lenp,
                             unsigned int __user *u_prio,
                             const void __user *u_ts,
                             int (*fetch_timeout)(struct timespec *ts,
@@ -1007,24 +1007,18 @@ int __cobalt_mq_timedreceive(mqd_t uqd, void __user 
*u_buf,
        struct cobalt_mqd *mqd;
        struct cobalt_msg *msg;
        unsigned int prio;
-       ssize_t len;
        int ret;
 
        mqd = cobalt_mqd_get(uqd);
        if (IS_ERR(mqd))
                return PTR_ERR(mqd);
 
-       if (__xn_get_user(len, u_len)) {
+       if (*lenp > 0 && !access_wok(u_buf, *lenp)) {
                ret = -EFAULT;
                goto fail;
        }
 
-       if (len > 0 && !access_wok(u_buf, len)) {
-               ret = -EFAULT;
-               goto fail;
-       }
-
-       msg = mq_timedrcv_inner(mqd, len, u_ts, fetch_timeout);
+       msg = mq_timedrcv_inner(mqd, *lenp, u_ts, fetch_timeout);
        if (IS_ERR(msg)) {
                ret = PTR_ERR(msg);
                goto fail;
@@ -1036,7 +1030,7 @@ int __cobalt_mq_timedreceive(mqd_t uqd, void __user 
*u_buf,
                goto fail;
        }
 
-       len = msg->len;
+       *lenp = msg->len;
        prio = msg->prio;
        ret = mq_finish_rcv(mqd, msg);
        if (ret)
@@ -1044,9 +1038,6 @@ int __cobalt_mq_timedreceive(mqd_t uqd, void __user 
*u_buf,
 
        cobalt_mqd_put(mqd);
 
-       if (__xn_put_user(len, u_len))
-               return -EFAULT;
-
        if (u_prio && __xn_put_user(prio, u_prio))
                return -EFAULT;
 
@@ -1063,8 +1054,17 @@ COBALT_SYSCALL(mq_timedreceive, primary,
                     unsigned int __user *u_prio,
                     const struct timespec __user *u_ts))
 {
-       return __cobalt_mq_timedreceive(uqd, u_buf, u_len, u_prio,
-                                       u_ts, u_ts ? mq_fetch_timeout : NULL);
+       ssize_t len;
+       int ret;
+
+       ret = __xn_safe_copy_from_user(&len, u_len, sizeof(len));
+       if (ret)
+               return ret;
+
+       ret = __cobalt_mq_timedreceive(uqd, u_buf, &len, u_prio,
+                                      u_ts, u_ts ? mq_fetch_timeout : NULL);
+
+       return ret ?: __xn_safe_copy_to_user(u_len, &len, sizeof(*u_len));
 }
 
 int cobalt_mq_pkg_init(void)
diff --git a/kernel/cobalt/posix/mqueue.h b/kernel/cobalt/posix/mqueue.h
index 8bdccd4..8fc42d0 100644
--- a/kernel/cobalt/posix/mqueue.h
+++ b/kernel/cobalt/posix/mqueue.h
@@ -44,7 +44,7 @@ int __cobalt_mq_timedsend(mqd_t uqd, const void __user 
*u_buf, size_t len,
                                               const void __user *u_ts));
 
 int __cobalt_mq_timedreceive(mqd_t uqd, void __user *u_buf,
-                            ssize_t __user *u_len,
+                            ssize_t *lenp,
                             unsigned int __user *u_prio,
                             const void __user *u_ts,
                             int (*fetch_timeout)(struct timespec *ts,
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 3074a3a..e813d21 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -264,14 +264,16 @@ COBALT_SYSCALL32emu(mq_timedreceive, primary,
        ssize_t len;
        int ret;
 
-       ret = __cobalt_mq_timedreceive(uqd, u_buf, &len, u_prio,
-                                      u_ts, u_ts ? sys32_fetch_timeout : NULL);
+       ret = __xn_safe_copy_from_user(&clen, u_len, sizeof(*u_len));
        if (ret)
                return ret;
 
+       len = clen;
+       ret = __cobalt_mq_timedreceive(uqd, u_buf, &len, u_prio,
+                                      u_ts, u_ts ? sys32_fetch_timeout : NULL);
        clen = len;
 
-       return __xn_safe_copy_to_user(u_len, &clen, sizeof(*u_len));
+       return ret ?: __xn_safe_copy_to_user(u_len, &clen, sizeof(*u_len));
 }
 
 COBALT_SYSCALL32emu(mq_notify, primary,


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to