From 8fd00b4d7014b00448eb33cf0590815304769798 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 26 Aug 2009 18:41:16 +0200 Subject: rlimits: security, add task_struct to setrlimit Add task_struct to task_setrlimit of security_operations to be able to set rlimit of task other than current. Signed-off-by: Jiri Slaby Acked-by: Eric Paris Acked-by: James Morris --- security/capability.c | 3 ++- security/security.c | 5 +++-- security/selinux/hooks.c | 7 ++++--- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'security') diff --git a/security/capability.c b/security/capability.c index 8168e3ecd5bf..7e468263f2de 100644 --- a/security/capability.c +++ b/security/capability.c @@ -412,7 +412,8 @@ static int cap_task_getioprio(struct task_struct *p) return 0; } -static int cap_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) +static int cap_task_setrlimit(struct task_struct *p, unsigned int resource, + struct rlimit *new_rlim) { return 0; } diff --git a/security/security.c b/security/security.c index 351942a4ca0e..aa510609a955 100644 --- a/security/security.c +++ b/security/security.c @@ -769,9 +769,10 @@ int security_task_getioprio(struct task_struct *p) return security_ops->task_getioprio(p); } -int security_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) +int security_task_setrlimit(struct task_struct *p, unsigned int resource, + struct rlimit *new_rlim) { - return security_ops->task_setrlimit(resource, new_rlim); + return security_ops->task_setrlimit(p, resource, new_rlim); } int security_task_setscheduler(struct task_struct *p, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5c9f25ba1c95..e3ce6b4127cc 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3371,16 +3371,17 @@ static int selinux_task_getioprio(struct task_struct *p) return current_has_perm(p, PROCESS__GETSCHED); } -static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) +static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, + struct rlimit *new_rlim) { - struct rlimit *old_rlim = current->signal->rlim + resource; + struct rlimit *old_rlim = p->signal->rlim + resource; /* Control the ability to change the hard limit (whether lowering or raising it), so that the hard limit can later be used as a safe reset point for the soft limit upon context transitions. See selinux_bprm_committing_creds. */ if (old_rlim->rlim_max != new_rlim->rlim_max) - return current_has_perm(current, PROCESS__SETRLIMIT); + return current_has_perm(p, PROCESS__SETRLIMIT); return 0; } -- cgit v1.2.3 From 5ab46b345e418747b3a52f0892680c0745c4223c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 28 Aug 2009 14:05:12 +0200 Subject: rlimits: add task_struct to update_rlimit_cpu Add task_struct as a parameter to update_rlimit_cpu to be able to set rlimit_cpu of different task than current. Signed-off-by: Jiri Slaby Acked-by: James Morris --- include/linux/posix-timers.h | 2 +- kernel/posix-cpu-timers.c | 8 ++++---- kernel/sys.c | 2 +- security/selinux/hooks.c | 3 ++- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'security') diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 4f71bf4e628c..3e23844a6990 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -117,6 +117,6 @@ void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx, long clock_nanosleep_restart(struct restart_block *restart_block); -void update_rlimit_cpu(unsigned long rlim_new); +void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new); #endif diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 9829646d399c..0513900995ce 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -16,13 +16,13 @@ * siglock protection since other code may update expiration cache as * well. */ -void update_rlimit_cpu(unsigned long rlim_new) +void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new) { cputime_t cputime = secs_to_cputime(rlim_new); - spin_lock_irq(¤t->sighand->siglock); - set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL); - spin_unlock_irq(¤t->sighand->siglock); + spin_lock_irq(&task->sighand->siglock); + set_process_cpu_timer(task, CPUCLOCK_PROF, &cputime, NULL); + spin_unlock_irq(&task->sighand->siglock); } static int check_clock(const clockid_t which_clock) diff --git a/kernel/sys.c b/kernel/sys.c index 1ba4522689d4..f5183b08adfc 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1320,7 +1320,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) if (new_rlim.rlim_cur == RLIM_INFINITY) goto out; - update_rlimit_cpu(new_rlim.rlim_cur); + update_rlimit_cpu(current, new_rlim.rlim_cur); out: return 0; } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index e3ce6b4127cc..afb18a9ebba1 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2338,7 +2338,8 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) initrlim = init_task.signal->rlim + i; rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); } - update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur); + update_rlimit_cpu(current, + current->signal->rlim[RLIMIT_CPU].rlim_cur); } } -- cgit v1.2.3 From eb2d55a32b9a91bca0dea299eedb560bafa8b14e Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 23 Jun 2010 22:43:32 +0200 Subject: rlimits: selinux, do rlimits changes under task_lock When doing an exec, selinux updates rlimits in its code of current process depending on current max. Make sure max or cur doesn't change in the meantime by grabbing task_lock which do_prlimit needs for changing limits too. While at it, use rlimit helper for accessing CPU rlimit a line below. To have a volatile access too. Signed-off-by: Jiri Slaby Cc: Oleg Nesterov --- security/selinux/hooks.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'security') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index afb18a9ebba1..2a8a0a915ff3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2333,13 +2333,15 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS, PROCESS__RLIMITINH, NULL); if (rc) { + /* protect against do_prlimit() */ + task_lock(current); for (i = 0; i < RLIM_NLIMITS; i++) { rlim = current->signal->rlim + i; initrlim = init_task.signal->rlim + i; rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); } - update_rlimit_cpu(current, - current->signal->rlim[RLIMIT_CPU].rlim_cur); + task_unlock(current); + update_rlimit_cpu(current, rlimit(RLIMIT_CPU)); } } -- cgit v1.2.3