[Xenomai-git] Philippe Gerum : cobalt/posix/compat: fix mq_timedreceive() for 32/ 64bit neutrality
Module: xenomai-3 Branch: master Commit: d8c9e4ec89151d625acaef8abd926a22d48f6a2a URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=d8c9e4ec89151d625acaef8abd926a22d48f6a2a Author: Philippe Gerum 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
[Xenomai-git] Philippe Gerum : cobalt/posix/compat: fix mq_timedreceive() for 32/ 64bit neutrality
Module: xenomai-3 Branch: next Commit: d8c9e4ec89151d625acaef8abd926a22d48f6a2a URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=d8c9e4ec89151d625acaef8abd926a22d48f6a2a Author: Philippe Gerum 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