[syscall][fix] kernel overwrite ustack data in timer create
This commit is contained in:
parent
892ef3dc5b
commit
31bfc855c1
|
@ -18,6 +18,7 @@
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
#include <mm_aspace.h>
|
#include <mm_aspace.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <lwp.h>
|
#include <lwp.h>
|
||||||
#ifdef ARCH_MM_MMU
|
#ifdef ARCH_MM_MMU
|
||||||
|
@ -1312,12 +1313,22 @@ rt_err_t sys_rt_timer_control(rt_timer_t timer, int cmd, void *arg)
|
||||||
return rt_timer_control(timer, cmd, arg);
|
return rt_timer_control(timer, cmd, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* MUSL compatible */
|
||||||
|
struct ksigevent
|
||||||
|
{
|
||||||
|
union sigval sigev_value;
|
||||||
|
int sigev_signo;
|
||||||
|
int sigev_notify;
|
||||||
|
int sigev_tid;
|
||||||
|
};
|
||||||
|
|
||||||
rt_err_t sys_timer_create(clockid_t clockid, struct sigevent *restrict sevp, timer_t *restrict timerid)
|
rt_err_t sys_timer_create(clockid_t clockid, struct sigevent *restrict sevp, timer_t *restrict timerid)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
#ifdef ARCH_MM_MMU
|
#ifdef ARCH_MM_MMU
|
||||||
struct sigevent sevp_k;
|
struct sigevent sevp_k;
|
||||||
timer_t timerid_k;
|
timer_t timerid_k;
|
||||||
|
int utimer;
|
||||||
|
|
||||||
if (sevp == NULL)
|
if (sevp == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1326,12 +1337,28 @@ rt_err_t sys_timer_create(clockid_t clockid, struct sigevent *restrict sevp, tim
|
||||||
sevp = &sevp_k;
|
sevp = &sevp_k;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
lwp_get_from_user(&sevp_k, (void *)sevp, sizeof sevp_k);
|
{
|
||||||
lwp_get_from_user(&timerid_k, (void *)timerid, sizeof timerid_k);
|
/* clear extra bytes if any */
|
||||||
|
if (sizeof(struct ksigevent) < sizeof(struct sigevent))
|
||||||
|
memset(&sevp_k, 0, sizeof(sevp_k));
|
||||||
|
|
||||||
|
/* musl passes `struct ksigevent` to kernel, we shoule only get size of that bytes */
|
||||||
|
lwp_get_from_user(&sevp_k, (void *)sevp, sizeof(struct ksigevent));
|
||||||
|
}
|
||||||
|
lwp_get_from_user(&timerid_k, (void *)timerid, sizeof(timerid_k));
|
||||||
|
|
||||||
|
/* to protect unsafe implementation in current rt-smart toolchain */
|
||||||
|
RT_ASSERT(((struct ksigevent *)sevp)->sigev_tid == (rt_ubase_t)sevp_k.sigev_notify_function);
|
||||||
|
|
||||||
ret = timer_create(clockid, &sevp_k, &timerid_k);
|
ret = timer_create(clockid, &sevp_k, &timerid_k);
|
||||||
|
|
||||||
|
/* ID should not extend 32-bits size for libc */
|
||||||
|
RT_ASSERT((rt_ubase_t)timerid_k < UINT32_MAX);
|
||||||
|
utimer = (rt_ubase_t)timerid_k;
|
||||||
|
|
||||||
if (ret != -RT_ERROR){
|
if (ret != -RT_ERROR){
|
||||||
lwp_put_to_user(sevp, (void *)&sevp_k, sizeof sevp_k);
|
lwp_put_to_user(sevp, (void *)&sevp_k, sizeof(struct ksigevent));
|
||||||
lwp_put_to_user(timerid, (void *)&timerid_k, sizeof timerid_k);
|
lwp_put_to_user(timerid, (void *)&utimer, sizeof(utimer));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
ret = timer_create(clockid, sevp, timerid);
|
ret = timer_create(clockid, sevp, timerid);
|
||||||
|
@ -1354,8 +1381,12 @@ rt_err_t sys_timer_settime(timer_t timerid, int flags,
|
||||||
struct itimerspec new_value_k;
|
struct itimerspec new_value_k;
|
||||||
struct itimerspec old_value_k;
|
struct itimerspec old_value_k;
|
||||||
|
|
||||||
lwp_get_from_user(&new_value_k, (void *)new_value, sizeof new_value_k);
|
if (!lwp_get_from_user(&new_value_k, (void *)new_value, sizeof(*new_value)) ||
|
||||||
lwp_get_from_user(&old_value_k, (void *)timerid, sizeof old_value_k);
|
(old_value && !lwp_get_from_user(&old_value_k, (void *)old_value, sizeof(*old_value))))
|
||||||
|
{
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
ret = timer_settime(timerid, flags, &new_value_k, &old_value_k);
|
ret = timer_settime(timerid, flags, &new_value_k, &old_value_k);
|
||||||
lwp_put_to_user(old_value, (void *)&old_value_k, sizeof old_value_k);
|
lwp_put_to_user(old_value, (void *)&old_value_k, sizeof old_value_k);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue