rlimits: do security check under task_lock
Do security_task_setrlimit under task_lock. Other tasks may change limits under our hands while we are checking limits inside the function. From now on, they can't. Note that all the security work is done under a spinlock here now. Security hooks count with that, they are called from interrupt context (like security_task_kill) and with spinlocks already held (e.g. capable->security_capable). Signed-off-by: Jiri Slaby <jslaby@suse.cz> Acked-by: James Morris <jmorris@namei.org> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
This commit is contained in:
Родитель
1c1e618ddd
Коммит
86f162f4c7
20
kernel/sys.c
20
kernel/sys.c
|
@ -1277,7 +1277,7 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
|
||||||
struct rlimit *new_rlim)
|
struct rlimit *new_rlim)
|
||||||
{
|
{
|
||||||
struct rlimit *old_rlim;
|
struct rlimit *old_rlim;
|
||||||
int retval;
|
int retval = 0;
|
||||||
|
|
||||||
if (resource >= RLIM_NLIMITS)
|
if (resource >= RLIM_NLIMITS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1293,9 +1293,14 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = security_task_setrlimit(tsk->group_leader, resource, new_rlim);
|
old_rlim = tsk->signal->rlim + resource;
|
||||||
if (retval)
|
task_lock(tsk->group_leader);
|
||||||
goto out;
|
if (new_rlim->rlim_max > old_rlim->rlim_max &&
|
||||||
|
!capable(CAP_SYS_RESOURCE))
|
||||||
|
retval = -EPERM;
|
||||||
|
if (!retval)
|
||||||
|
retval = security_task_setrlimit(tsk->group_leader, resource,
|
||||||
|
new_rlim);
|
||||||
|
|
||||||
if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
|
if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
|
||||||
/*
|
/*
|
||||||
|
@ -1307,12 +1312,7 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
|
||||||
new_rlim->rlim_cur = 1;
|
new_rlim->rlim_cur = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_rlim = tsk->signal->rlim + resource;
|
if (!retval)
|
||||||
task_lock(tsk->group_leader);
|
|
||||||
if (new_rlim->rlim_max > old_rlim->rlim_max &&
|
|
||||||
!capable(CAP_SYS_RESOURCE))
|
|
||||||
retval = -EPERM;
|
|
||||||
else
|
|
||||||
*old_rlim = *new_rlim;
|
*old_rlim = *new_rlim;
|
||||||
task_unlock(tsk->group_leader);
|
task_unlock(tsk->group_leader);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче