lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 19 Oct 2009 20:53:29 -0400 From: Neil Horman <nhorman@...driver.com> To: linux-kernel@...r.kernel.org Cc: akpm@...ux-foundation.org, marcin.slusarz@...il.com, tglx@...utronix.de, mingo@...hat.com, hpa@...or.com, nhorman@...driver.com Subject: Re: [PATCH 1/3] extend get/setrlimit to support setting rlimits external to a process (v7) Modify setrlimit syscall to accomodate various usages. Split the sys_setrlimit syscall into two parts: 1) a DEFINE_SYSCALL wrapper that implements the sys_setrlimit function 2) a core do_setrlimit function that accepts as a parameter a task on which to operate on the limits of This allows us later to implement sys_setprlimit, which allows us to change the limits of any process from userspace Signed-off-by: Neil Horman <nhorman@...driver.com include/linux/sched.h | 3 +++ kernel/sys.c | 48 ++++++++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 7755763..ce95005 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -672,6 +672,9 @@ struct signal_struct { int oom_adj; /* OOM kill score adjustment (bit shift) */ }; +extern int do_setrlimit(unsigned int resource, struct rlimit *new_rlim, + struct task_struct *tsk); + /* Context switch must be unlocked if interrupts are to be enabled */ #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW # define __ARCH_WANT_UNLOCKED_CTXSW diff --git a/kernel/sys.c b/kernel/sys.c index 1828f8d..0e210a4 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1238,41 +1238,41 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource, #endif -SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) +int do_setrlimit(unsigned int resource, struct rlimit *new_rlim, + struct task_struct *tsk) { - struct rlimit new_rlim, *old_rlim; int retval; + struct rlimit *old_rlim; - if (resource >= RLIM_NLIMITS) - return -EINVAL; - if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) - return -EFAULT; - if (new_rlim.rlim_cur > new_rlim.rlim_max) + + if (new_rlim->rlim_cur > new_rlim->rlim_max) return -EINVAL; - old_rlim = current->signal->rlim + resource; - if ((new_rlim.rlim_max > old_rlim->rlim_max) && + old_rlim = tsk->signal->rlim + resource; + + if ((new_rlim->rlim_max > old_rlim->rlim_max) && !capable(CAP_SYS_RESOURCE)) return -EPERM; - if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) + + if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open) return -EPERM; - retval = security_task_setrlimit(resource, &new_rlim); + retval = security_task_setrlimit(resource, new_rlim); if (retval) return retval; - if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) { + if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) { /* * The caller is asking for an immediate RLIMIT_CPU * expiry. But we use the zero value to mean "it was * never set". So let's cheat and make it one second * instead */ - new_rlim.rlim_cur = 1; + new_rlim->rlim_cur = 1; } - task_lock(current->group_leader); - *old_rlim = new_rlim; - task_unlock(current->group_leader); + task_lock(tsk->group_leader); + *old_rlim = *new_rlim; + task_unlock(tsk->group_leader); if (resource != RLIMIT_CPU) goto out; @@ -1283,14 +1283,26 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) * very long-standing error, and fixing it now risks breakage of * applications, so we live with it */ - if (new_rlim.rlim_cur == RLIM_INFINITY) + if (new_rlim->rlim_cur == RLIM_INFINITY) goto out; - update_rlimit_cpu(new_rlim.rlim_cur); + update_rlimit_cpu(new_rlim->rlim_cur); out: return 0; } +SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) +{ + struct rlimit new_rlim; + + if (resource >= RLIM_NLIMITS) + return -EINVAL; + if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) + return -EFAULT; + + return do_setrlimit(resource, &new_rlim, current); +} + /* * It would make sense to put struct rusage in the task_struct, * except that would make the task_struct be *really big*. After -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists