mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-30 05:25:20 +08:00
compat: nanosleep: Clarify error handling
The error handling in compat_sys_nanosleep() is correct, but completely non obvious. Document it and restrict it to the -ERESTART_RESTARTBLOCK return value for clarity. Reported-by: Kees Cook <keescook@chromium.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
40bea03959
commit
849151dd54
@ -226,7 +226,7 @@ static long compat_nanosleep_restart(struct restart_block *restart)
|
|||||||
ret = hrtimer_nanosleep_restart(restart);
|
ret = hrtimer_nanosleep_restart(restart);
|
||||||
set_fs(oldfs);
|
set_fs(oldfs);
|
||||||
|
|
||||||
if (ret) {
|
if (ret == -ERESTART_RESTARTBLOCK) {
|
||||||
rmtp = restart->nanosleep.compat_rmtp;
|
rmtp = restart->nanosleep.compat_rmtp;
|
||||||
|
|
||||||
if (rmtp && compat_put_timespec(&rmt, rmtp))
|
if (rmtp && compat_put_timespec(&rmt, rmtp))
|
||||||
@ -256,7 +256,26 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
|
|||||||
HRTIMER_MODE_REL, CLOCK_MONOTONIC);
|
HRTIMER_MODE_REL, CLOCK_MONOTONIC);
|
||||||
set_fs(oldfs);
|
set_fs(oldfs);
|
||||||
|
|
||||||
if (ret) {
|
/*
|
||||||
|
* hrtimer_nanosleep() can only return 0 or
|
||||||
|
* -ERESTART_RESTARTBLOCK here because:
|
||||||
|
*
|
||||||
|
* - we call it with HRTIMER_MODE_REL and therefor exclude the
|
||||||
|
* -ERESTARTNOHAND return path.
|
||||||
|
*
|
||||||
|
* - we supply the rmtp argument from the task stack (due to
|
||||||
|
* the necessary compat conversion. So the update cannot
|
||||||
|
* fail, which excludes the -EFAULT return path as well. If
|
||||||
|
* it fails nevertheless we have a bigger problem and wont
|
||||||
|
* reach this place anymore.
|
||||||
|
*
|
||||||
|
* - if the return value is 0, we do not have to update rmtp
|
||||||
|
* because there is no remaining time.
|
||||||
|
*
|
||||||
|
* We check for -ERESTART_RESTARTBLOCK nevertheless if the
|
||||||
|
* core implementation decides to return random nonsense.
|
||||||
|
*/
|
||||||
|
if (ret == -ERESTART_RESTARTBLOCK) {
|
||||||
struct restart_block *restart
|
struct restart_block *restart
|
||||||
= ¤t_thread_info()->restart_block;
|
= ¤t_thread_info()->restart_block;
|
||||||
|
|
||||||
@ -266,7 +285,6 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
|
|||||||
if (rmtp && compat_put_timespec(&rmt, rmtp))
|
if (rmtp && compat_put_timespec(&rmt, rmtp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user