* [PATCH v3 02/27] SECURITY: add task_struct to setrlimit
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 03/27] core: add task_struct to update_rlimit_cpu Jiri Slaby
` (25 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
From: Jiri Slaby <jirislaby@gmail.com>
Add task_struct to task_setrlimit of security_operations to be able to set
rlimit of different task than current.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Acked-by: Eric Paris <eparis@redhat.com>
Acked-by: James Morris <jmorris@namei.org>
---
include/linux/security.h | 9 ++++++---
kernel/sys.c | 2 +-
security/capability.c | 3 ++-
security/security.c | 5 +++--
security/selinux/hooks.c | 7 ++++---
5 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/include/linux/security.h b/include/linux/security.h
index 239e40d..193b3d9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1570,7 +1570,8 @@ struct security_operations {
int (*task_setnice) (struct task_struct *p, int nice);
int (*task_setioprio) (struct task_struct *p, int ioprio);
int (*task_getioprio) (struct task_struct *p);
- int (*task_setrlimit) (unsigned int resource, struct rlimit *new_rlim);
+ int (*task_setrlimit) (struct task_struct *p, unsigned int resource,
+ struct rlimit *new_rlim);
int (*task_setscheduler) (struct task_struct *p, int policy,
struct sched_param *lp);
int (*task_getscheduler) (struct task_struct *p);
@@ -1835,7 +1836,8 @@ int security_task_setgroups(struct group_info *group_info);
int security_task_setnice(struct task_struct *p, int nice);
int security_task_setioprio(struct task_struct *p, int ioprio);
int security_task_getioprio(struct task_struct *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);
int security_task_setscheduler(struct task_struct *p,
int policy, struct sched_param *lp);
int security_task_getscheduler(struct task_struct *p);
@@ -2451,7 +2453,8 @@ static inline int security_task_getioprio(struct task_struct *p)
return 0;
}
-static inline int security_task_setrlimit(unsigned int resource,
+static inline int security_task_setrlimit(struct task_struct *p,
+ unsigned int resource,
struct rlimit *new_rlim)
{
return 0;
diff --git a/kernel/sys.c b/kernel/sys.c
index ce17760..9898a8a 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1256,7 +1256,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
return -EPERM;
- retval = security_task_setrlimit(resource, &new_rlim);
+ retval = security_task_setrlimit(current, resource, &new_rlim);
if (retval)
return retval;
diff --git a/security/capability.c b/security/capability.c
index fce07a7..5882ec0 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -450,7 +450,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 c4c6732..4b23d83 100644
--- a/security/security.c
+++ b/security/security.c
@@ -781,9 +781,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 36d9e25..1167f01 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3390,16 +3390,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;
}
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 03/27] core: add task_struct to update_rlimit_cpu
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 02/27] SECURITY: add task_struct to setrlimit Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 04/27] sys_setrlimit: make sure ->rlim_max never grows Jiri Slaby
` (24 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
From: Jiri Slaby <jirislaby@gmail.com>
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 <jirislaby@gmail.com>
Acked-by: James Morris <jmorris@namei.org>
---
include/linux/posix-timers.h | 2 +-
kernel/posix-cpu-timers.c | 10 +++++-----
kernel/sys.c | 2 +-
security/selinux/hooks.c | 3 ++-
4 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 4f71bf4..3e23844 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 5c9dc22..102c345 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -13,16 +13,16 @@
/*
* Called after updating RLIMIT_CPU to set timer expiration if necessary.
*/
-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);
- struct signal_struct *const sig = current->signal;
+ struct signal_struct *const sig = task->signal;
if (cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) ||
cputime_gt(sig->it[CPUCLOCK_PROF].expires, cputime)) {
- 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);
}
}
diff --git a/kernel/sys.c b/kernel/sys.c
index 9898a8a..71e4eb1 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1286,7 +1286,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 1167f01..dac6c88 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2366,7 +2366,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);
}
}
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 04/27] sys_setrlimit: make sure ->rlim_max never grows
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 02/27] SECURITY: add task_struct to setrlimit Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 03/27] core: add task_struct to update_rlimit_cpu Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 05/27] core: split sys_setrlimit Jiri Slaby
` (23 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
From: Oleg Nesterov <oleg@redhat.com>
Mostly preparation for Jiri's changes, but probably makes sense anyway.
sys_setrlimit() checks new_rlim.rlim_max <= old_rlim->rlim_max, but when
it takes task_lock() old_rlim->rlim_max can be already lowered. Move this
check under task_lock().
Currently this is not important, we can only race with our sub-thread,
this means the application is stupid. But when we change the code to allow
the update of !current task's limits, it becomes important to make sure
->rlim_max can be lowered "reliably" even if we race with the application
doing sys_setrlimit().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
kernel/sys.c | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/kernel/sys.c b/kernel/sys.c
index 71e4eb1..4377cb3 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1249,10 +1249,6 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
return -EFAULT;
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) &&
- !capable(CAP_SYS_RESOURCE))
- return -EPERM;
if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
return -EPERM;
@@ -1270,11 +1266,16 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
new_rlim.rlim_cur = 1;
}
+ old_rlim = current->signal->rlim + resource;
task_lock(current->group_leader);
- *old_rlim = new_rlim;
+ if ((new_rlim.rlim_max <= old_rlim->rlim_max) ||
+ capable(CAP_SYS_RESOURCE))
+ *old_rlim = new_rlim;
+ else
+ retval = -EPERM;
task_unlock(current->group_leader);
- if (resource != RLIMIT_CPU)
+ if (retval || resource != RLIMIT_CPU)
goto out;
/*
@@ -1288,7 +1289,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
update_rlimit_cpu(current, new_rlim.rlim_cur);
out:
- return 0;
+ return retval;
}
/*
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 05/27] core: split sys_setrlimit
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (2 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 04/27] sys_setrlimit: make sure ->rlim_max never grows Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 06/27] core: allow setrlimit to non-current tasks Jiri Slaby
` (22 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
From: Jiri Slaby <jirislaby@gmail.com>
Create setrlimit from sys_setrlimit and declare setrlimit in
the resource header. This is to allow rlimits to be changed not
only by syscall, but later from proc code too.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
include/linux/resource.h | 2 ++
kernel/sys.c | 44 ++++++++++++++++++++++++++------------------
2 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/include/linux/resource.h b/include/linux/resource.h
index 40fc7e6..4301d67 100644
--- a/include/linux/resource.h
+++ b/include/linux/resource.h
@@ -71,5 +71,7 @@ struct rlimit {
#include <asm/resource.h>
int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
+int setrlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim);
#endif
diff --git a/kernel/sys.c b/kernel/sys.c
index 4377cb3..398f9e1 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1238,42 +1238,39 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
#endif
-SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
+int setrlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim)
{
- struct rlimit new_rlim, *old_rlim;
+ struct rlimit *old_rlim;
int retval;
- 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;
- 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(current, resource, &new_rlim);
+ retval = security_task_setrlimit(tsk, 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;
}
- old_rlim = current->signal->rlim + resource;
- task_lock(current->group_leader);
- if ((new_rlim.rlim_max <= old_rlim->rlim_max) ||
+ old_rlim = tsk->signal->rlim + resource;
+ task_lock(tsk->group_leader);
+ if ((new_rlim->rlim_max <= old_rlim->rlim_max) ||
capable(CAP_SYS_RESOURCE))
- *old_rlim = new_rlim;
+ *old_rlim = *new_rlim;
else
retval = -EPERM;
- task_unlock(current->group_leader);
+ task_unlock(tsk->group_leader);
if (retval || resource != RLIMIT_CPU)
goto out;
@@ -1284,14 +1281,25 @@ 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(current, new_rlim.rlim_cur);
+ update_rlimit_cpu(tsk, new_rlim->rlim_cur);
out:
return retval;
}
+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 setrlimit(current, resource, &new_rlim);
+}
+
/*
* It would make sense to put struct rusage in the task_struct,
* except that would make the task_struct be *really big*. After
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 06/27] core: allow setrlimit to non-current tasks
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (3 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 05/27] core: split sys_setrlimit Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 07/27] core: optimize setrlimit for current task Jiri Slaby
` (21 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
From: Jiri Slaby <jirislaby@gmail.com>
Add locking to allow setrlimit accept task parameter other than
current.
Namely, lock tasklist_lock for read and check whether the task
structure has sighand non-null. Do all the signal processing under
that lock still held.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Oleg Nesterov <oleg@redhat.com>
---
kernel/sys.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/kernel/sys.c b/kernel/sys.c
index 398f9e1..3082eaf 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1238,6 +1238,7 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
#endif
+/* make sure you are allowed to change @tsk limits before calling this */
int setrlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim)
{
@@ -1249,9 +1250,16 @@ int setrlimit(struct task_struct *tsk, unsigned int resource,
if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
return -EPERM;
+ /* protect tsk->signal and tsk->sighand from disappearing */
+ read_lock(&tasklist_lock);
+ if (!tsk->sighand) {
+ retval = -ESRCH;
+ goto out;
+ }
+
retval = security_task_setrlimit(tsk, resource, new_rlim);
if (retval)
- return retval;
+ goto out;
if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
/*
@@ -1286,6 +1294,7 @@ int setrlimit(struct task_struct *tsk, unsigned int resource,
update_rlimit_cpu(tsk, new_rlim->rlim_cur);
out:
+ read_unlock(&tasklist_lock);
return retval;
}
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 07/27] core: optimize setrlimit for current task
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (4 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 06/27] core: allow setrlimit to non-current tasks Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 08/27] FS: proc, switch limits reading to fops Jiri Slaby
` (20 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
From: Jiri Slaby <jirislaby@gmail.com>
Don't take tasklist lock for 'current'. It's not needed, since
current->sighand/signal can't disappear.
This improves serlimit called especially via sys_setrlimit.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Oleg Nesterov <oleg@redhat.com>
---
kernel/sys.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/kernel/sys.c b/kernel/sys.c
index 3082eaf..605ab9c 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1250,11 +1250,14 @@ int setrlimit(struct task_struct *tsk, unsigned int resource,
if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
return -EPERM;
- /* protect tsk->signal and tsk->sighand from disappearing */
- read_lock(&tasklist_lock);
- if (!tsk->sighand) {
- retval = -ESRCH;
- goto out;
+ /* optimization: 'current' doesn't need locking, e.g. setrlimit */
+ if (tsk != current) {
+ /* protect tsk->signal and tsk->sighand from disappearing */
+ read_lock(&tasklist_lock);
+ if (!tsk->sighand) {
+ retval = -ESRCH;
+ goto out;
+ }
}
retval = security_task_setrlimit(tsk, resource, new_rlim);
@@ -1294,7 +1297,8 @@ int setrlimit(struct task_struct *tsk, unsigned int resource,
update_rlimit_cpu(tsk, new_rlim->rlim_cur);
out:
- read_unlock(&tasklist_lock);
+ if (tsk != current)
+ read_unlock(&tasklist_lock);
return retval;
}
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 08/27] FS: proc, switch limits reading to fops
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (5 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 07/27] core: optimize setrlimit for current task Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 09/27] FS: proc, make limits writable Jiri Slaby
` (19 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
From: Jiri Slaby <jirislaby@gmail.com>
Use fops instead of proc_info_read. We will need fops for limits
writing and the code would look ugly if we used
NOD("limits", S_IFREG|S_IRUSR|S_IWUSR, NULL,
&proc_pid_limits_operations, { .proc_read = proc_pid_limits }),
We will just use
REG("limits", S_IRUSR|S_IWUSR, proc_pid_limits_operations),
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
fs/proc/base.c | 37 ++++++++++++++++++++++++++++---------
1 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index af643b5..be4733c 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -477,19 +477,30 @@ static const struct limit_names lnames[RLIM_NLIMITS] = {
};
/* Display limits for a process */
-static int proc_pid_limits(struct task_struct *task, char *buffer)
+static ssize_t limits_read(struct file *file, char __user *buf, size_t rcount,
+ loff_t *ppos)
{
- unsigned int i;
- int count = 0;
- unsigned long flags;
- char *bufptr = buffer;
-
struct rlimit rlim[RLIM_NLIMITS];
+ struct task_struct *task;
+ unsigned long flags;
+ unsigned int i;
+ ssize_t count = 0;
+ char *bufptr;
- if (!lock_task_sighand(task, &flags))
+ task = get_proc_task(file->f_path.dentry->d_inode);
+ if (!task)
+ return -ESRCH;
+ if (!lock_task_sighand(task, &flags)) {
+ put_task_struct(task);
return 0;
+ }
memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
unlock_task_sighand(task, &flags);
+ put_task_struct(task);
+
+ bufptr = (char *)__get_free_page(GFP_TEMPORARY);
+ if (!bufptr)
+ return -ENOMEM;
/*
* print the file header
@@ -518,9 +529,17 @@ static int proc_pid_limits(struct task_struct *task, char *buffer)
count += sprintf(&bufptr[count], "\n");
}
+ count = simple_read_from_buffer(buf, rcount, ppos, bufptr, count);
+
+ free_page((unsigned long)bufptr);
+
return count;
}
+static const struct file_operations proc_pid_limits_operations = {
+ .read = limits_read,
+};
+
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
static int proc_pid_syscall(struct task_struct *task, char *buffer)
{
@@ -2500,7 +2519,7 @@ static const struct pid_entry tgid_base_stuff[] = {
INF("auxv", S_IRUSR, proc_pid_auxv),
ONE("status", S_IRUGO, proc_pid_status),
ONE("personality", S_IRUSR, proc_pid_personality),
- INF("limits", S_IRUSR, proc_pid_limits),
+ REG("limits", S_IRUSR, proc_pid_limits_operations),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
@@ -2834,7 +2853,7 @@ static const struct pid_entry tid_base_stuff[] = {
INF("auxv", S_IRUSR, proc_pid_auxv),
ONE("status", S_IRUGO, proc_pid_status),
ONE("personality", S_IRUSR, proc_pid_personality),
- INF("limits", S_IRUSR, proc_pid_limits),
+ REG("limits", S_IRUSR, proc_pid_limits_operations),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 09/27] FS: proc, make limits writable
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (6 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 08/27] FS: proc, switch limits reading to fops Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 10/27] core: do security check under task_lock Jiri Slaby
` (18 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
From: Jiri Slaby <jirislaby@gmail.com>
Allow writing strings such as
Max core file size=0:unlimited
to /proc/<pid>/limits to change limits.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
fs/proc/base.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index be4733c..78c0367 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -536,8 +536,72 @@ static ssize_t limits_read(struct file *file, char __user *buf, size_t rcount,
return count;
}
+static ssize_t limits_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+ char str[32 + 1 + 16 + 1 + 16 + 1], *delim, *next;
+ struct rlimit new_rlimit;
+ unsigned int i;
+ int ret;
+
+ if (!task) {
+ count = -ESRCH;
+ goto out;
+ }
+ if (copy_from_user(str, buf, min(count, sizeof(str) - 1))) {
+ count = -EFAULT;
+ goto put_task;
+ }
+
+ str[min(count, sizeof(str) - 1)] = 0;
+
+ delim = strchr(str, '=');
+ if (!delim) {
+ count = -EINVAL;
+ goto put_task;
+ }
+ *delim++ = 0; /* for easy 'str' usage */
+ new_rlimit.rlim_cur = simple_strtoul(delim, &next, 0);
+ if (*next != ':') {
+ if (strncmp(delim, "unlimited:", 10)) {
+ count = -EINVAL;
+ goto put_task;
+ }
+ new_rlimit.rlim_cur = RLIM_INFINITY;
+ next = delim + 9; /* move to ':' */
+ }
+ delim = next + 1;
+ new_rlimit.rlim_max = simple_strtoul(delim, &next, 0);
+ if (*next != 0) {
+ if (strcmp(delim, "unlimited")) {
+ count = -EINVAL;
+ goto put_task;
+ }
+ new_rlimit.rlim_max = RLIM_INFINITY;
+ }
+
+ for (i = 0; i < RLIM_NLIMITS; i++)
+ if (!strcmp(str, lnames[i].name))
+ break;
+ if (i >= RLIM_NLIMITS) {
+ count = -EINVAL;
+ goto put_task;
+ }
+
+ ret = setrlimit(task, i, &new_rlimit);
+ if (ret)
+ count = ret;
+
+put_task:
+ put_task_struct(task);
+out:
+ return count;
+}
+
static const struct file_operations proc_pid_limits_operations = {
.read = limits_read,
+ .write = limits_write,
};
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
@@ -2519,7 +2583,7 @@ static const struct pid_entry tgid_base_stuff[] = {
INF("auxv", S_IRUSR, proc_pid_auxv),
ONE("status", S_IRUGO, proc_pid_status),
ONE("personality", S_IRUSR, proc_pid_personality),
- REG("limits", S_IRUSR, proc_pid_limits_operations),
+ REG("limits", S_IRUSR|S_IWUSR, proc_pid_limits_operations),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
@@ -2853,7 +2917,7 @@ static const struct pid_entry tid_base_stuff[] = {
INF("auxv", S_IRUSR, proc_pid_auxv),
ONE("status", S_IRUGO, proc_pid_status),
ONE("personality", S_IRUSR, proc_pid_personality),
- REG("limits", S_IRUSR, proc_pid_limits_operations),
+ REG("limits", S_IRUSR|S_IWUSR, proc_pid_limits_operations),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 10/27] core: do security check under task_lock
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (7 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 09/27] FS: proc, make limits writable Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 11/27] core: rename setrlimit to do_setrlimit Jiri Slaby
` (17 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, Heiko Carstens
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.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
---
kernel/sys.c | 16 +++++++---------
1 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/kernel/sys.c b/kernel/sys.c
index 605ab9c..0f86199 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1243,7 +1243,7 @@ int setrlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim)
{
struct rlimit *old_rlim;
- int retval;
+ int retval = 0;
if (new_rlim->rlim_cur > new_rlim->rlim_max)
return -EINVAL;
@@ -1260,10 +1260,6 @@ int setrlimit(struct task_struct *tsk, unsigned int resource,
}
}
- retval = security_task_setrlimit(tsk, resource, new_rlim);
- if (retval)
- goto out;
-
if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
/*
* The caller is asking for an immediate RLIMIT_CPU
@@ -1276,11 +1272,13 @@ int setrlimit(struct task_struct *tsk, unsigned int resource,
old_rlim = tsk->signal->rlim + resource;
task_lock(tsk->group_leader);
- if ((new_rlim->rlim_max <= old_rlim->rlim_max) ||
- capable(CAP_SYS_RESOURCE))
- *old_rlim = *new_rlim;
- else
+ if ((new_rlim->rlim_max > old_rlim->rlim_max) &&
+ !capable(CAP_SYS_RESOURCE))
retval = -EPERM;
+ if (!retval)
+ retval = security_task_setrlimit(tsk, resource, new_rlim);
+ if (!retval)
+ *old_rlim = *new_rlim;
task_unlock(tsk->group_leader);
if (retval || resource != RLIMIT_CPU)
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 11/27] core: rename setrlimit to do_setrlimit
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (8 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 10/27] core: do security check under task_lock Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 12/27] resource: move kernel functions inside __KERNEL__ Jiri Slaby
` (16 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens
Rename it so that it makes more sense in the field of syscalls
(i.e. do_* is used for functions called by syscall wrappers but
also when called from other paths).
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Reviewed-by: WANG Cong <xiyou.wangcong@gmail.com>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
---
fs/proc/base.c | 2 +-
include/linux/resource.h | 2 +-
kernel/sys.c | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 78c0367..9fdb990 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -589,7 +589,7 @@ static ssize_t limits_write(struct file *file, const char __user *buf,
goto put_task;
}
- ret = setrlimit(task, i, &new_rlimit);
+ ret = do_setrlimit(task, i, &new_rlimit);
if (ret)
count = ret;
diff --git a/include/linux/resource.h b/include/linux/resource.h
index 4301d67..08beb1a 100644
--- a/include/linux/resource.h
+++ b/include/linux/resource.h
@@ -71,7 +71,7 @@ struct rlimit {
#include <asm/resource.h>
int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
-int setrlimit(struct task_struct *tsk, unsigned int resource,
+int do_setrlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim);
#endif
diff --git a/kernel/sys.c b/kernel/sys.c
index 0f86199..fad6010 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1239,7 +1239,7 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
#endif
/* make sure you are allowed to change @tsk limits before calling this */
-int setrlimit(struct task_struct *tsk, unsigned int resource,
+int do_setrlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim)
{
struct rlimit *old_rlim;
@@ -1308,7 +1308,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
return -EINVAL;
if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
return -EFAULT;
- return setrlimit(current, resource, &new_rlim);
+ return do_setrlimit(current, resource, &new_rlim);
}
/*
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 12/27] resource: move kernel functions inside __KERNEL__
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (9 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 11/27] core: rename setrlimit to do_setrlimit Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 13/27] core: posix-cpu-timers, cleanup rlimits usage Jiri Slaby
` (15 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg
These are internal functions. Move them inside __KERNEL__ ifdef.
This needs also unifdef of resource.h before installing. Change
that too.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
include/linux/Kbuild | 2 +-
include/linux/resource.h | 8 ++++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 1feed71..a73a9c2 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -140,7 +140,6 @@ header-y += qnxtypes.h
header-y += qnx4_fs.h
header-y += radeonfb.h
header-y += raw.h
-header-y += resource.h
header-y += romfs_fs.h
header-y += rose.h
header-y += serial_reg.h
@@ -323,6 +322,7 @@ unifdef-y += irqnr.h
unifdef-y += reboot.h
unifdef-y += reiserfs_fs.h
unifdef-y += reiserfs_xattr.h
+unifdef-y += resource.h
unifdef-y += route.h
unifdef-y += rtc.h
unifdef-y += rtnetlink.h
diff --git a/include/linux/resource.h b/include/linux/resource.h
index 08beb1a..cf8dc96 100644
--- a/include/linux/resource.h
+++ b/include/linux/resource.h
@@ -3,8 +3,6 @@
#include <linux/time.h>
-struct task_struct;
-
/*
* Resource control/accounting header file for linux
*/
@@ -70,8 +68,14 @@ struct rlimit {
*/
#include <asm/resource.h>
+#ifdef __KERNEL__
+
+struct task_struct;
+
int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
int do_setrlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim);
+#endif /* __KERNEL__ */
+
#endif
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 13/27] core: posix-cpu-timers, cleanup rlimits usage
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (10 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 12/27] resource: move kernel functions inside __KERNEL__ Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 14/27] resource: add helpers for fetching rlimits Jiri Slaby
` (14 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Peter Zijlstra
Fetch rlimit (both hard and soft) values only once and work on them.
It removes many accesses through sig structure and makes the code
cleaner.
Mostly a preparation for writable resource limits support.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
---
kernel/posix-cpu-timers.c | 32 +++++++++++++++++---------------
1 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 102c345..a7dcce1 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -983,6 +983,7 @@ static void check_thread_timers(struct task_struct *tsk,
int maxfire;
struct list_head *timers = tsk->cpu_timers;
struct signal_struct *const sig = tsk->signal;
+ unsigned long soft;
maxfire = 20;
tsk->cputime_expires.prof_exp = cputime_zero;
@@ -1031,9 +1032,9 @@ static void check_thread_timers(struct task_struct *tsk,
/*
* Check for the special case thread timers.
*/
- if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) {
+ soft = sig->rlim[RLIMIT_RTTIME].rlim_cur;
+ if (soft != RLIM_INFINITY) {
unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max;
- unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur;
if (hard != RLIM_INFINITY &&
tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
@@ -1044,14 +1045,13 @@ static void check_thread_timers(struct task_struct *tsk,
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
- if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) {
+ if (tsk->rt.timeout > DIV_ROUND_UP(soft, USEC_PER_SEC/HZ)) {
/*
* At the soft limit, send a SIGXCPU every second.
*/
- if (sig->rlim[RLIMIT_RTTIME].rlim_cur
- < sig->rlim[RLIMIT_RTTIME].rlim_max) {
- sig->rlim[RLIMIT_RTTIME].rlim_cur +=
- USEC_PER_SEC;
+ if (soft < hard) {
+ soft += USEC_PER_SEC;
+ sig->rlim[RLIMIT_RTTIME].rlim_cur = soft;
}
printk(KERN_INFO
"RT Watchdog Timeout: %s[%d]\n",
@@ -1122,13 +1122,14 @@ static void check_process_timers(struct task_struct *tsk,
unsigned long long sum_sched_runtime, sched_expires;
struct list_head *timers = sig->cpu_timers;
struct task_cputime cputime;
+ unsigned long cpu_cur_lim = sig->rlim[RLIMIT_CPU].rlim_cur;
/*
* Don't sample the current process CPU clocks if there are no timers.
*/
if (list_empty(&timers[CPUCLOCK_PROF]) &&
cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) &&
- sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY &&
+ cpu_cur_lim == RLIM_INFINITY &&
list_empty(&timers[CPUCLOCK_VIRT]) &&
cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) &&
list_empty(&timers[CPUCLOCK_SCHED])) {
@@ -1195,10 +1196,11 @@ static void check_process_timers(struct task_struct *tsk,
check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime,
SIGVTALRM);
- if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
+ if (cpu_cur_lim != RLIM_INFINITY) {
unsigned long psecs = cputime_to_secs(ptime);
+ unsigned long hard = sig->rlim[RLIMIT_CPU].rlim_max;
cputime_t x;
- if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) {
+ if (psecs >= hard) {
/*
* At the hard limit, we just die.
* No need to calculate anything else now.
@@ -1206,17 +1208,17 @@ static void check_process_timers(struct task_struct *tsk,
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
- if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
+ if (psecs >= cpu_cur_lim) {
/*
* At the soft limit, send a SIGXCPU every second.
*/
__group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
- if (sig->rlim[RLIMIT_CPU].rlim_cur
- < sig->rlim[RLIMIT_CPU].rlim_max) {
- sig->rlim[RLIMIT_CPU].rlim_cur++;
+ if (cpu_cur_lim < hard) {
+ cpu_cur_lim++;
+ sig->rlim[RLIMIT_CPU].rlim_cur = cpu_cur_lim;
}
}
- x = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
+ x = secs_to_cputime(cpu_cur_lim);
if (cputime_eq(prof_expires, cputime_zero) ||
cputime_lt(x, prof_expires)) {
prof_expires = x;
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 14/27] resource: add helpers for fetching rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (11 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 13/27] core: posix-cpu-timers, cleanup rlimits usage Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 15/27] IA64: use helpers for rlimits Jiri Slaby
` (13 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens
We want to be sure that compiler fetches the limit variable only
once, so add helpers for fetching current and maximal resource
limits which do that.
Add them to sched.h (instead of resource.h) due to circular dependency
sched.h->resource.h->task_struct
Alternative would be to create a separate res_access.h or similar.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
---
include/linux/sched.h | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 75e6e60..cf4205b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2574,6 +2574,28 @@ static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
}
#endif /* CONFIG_MM_OWNER */
+static inline unsigned long task_rlim_get_cur(const struct task_struct *tsk,
+ unsigned int limit)
+{
+ return ACCESS_ONCE(tsk->signal->rlim[limit].rlim_cur);
+}
+
+static inline unsigned long task_rlim_get_max(const struct task_struct *tsk,
+ unsigned int limit)
+{
+ return ACCESS_ONCE(tsk->signal->rlim[limit].rlim_max);
+}
+
+static inline unsigned long rlim_get_cur(unsigned int limit)
+{
+ return task_rlim_get_cur(current, limit);
+}
+
+static inline unsigned long rlim_get_max(unsigned int limit)
+{
+ return task_rlim_get_max(current, limit);
+}
+
#define TASK_STATE_TO_CHAR_STR "RSDTtZX"
#endif /* __KERNEL__ */
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 15/27] IA64: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (12 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 14/27] resource: add helpers for fetching rlimits Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 16/27] PPC: " Jiri Slaby
` (12 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
linux-ia64
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/kernel/perfmon.c | 2 +-
arch/ia64/kernel/sys_ia64.c | 2 +-
arch/ia64/mm/init.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f178270..82429cc 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2298,7 +2298,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
* if ((mm->total_vm << PAGE_SHIFT) + len> task->rlim[RLIMIT_AS].rlim_cur)
* return -ENOMEM;
*/
- if (size > task->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
+ if (size > task_rlim_get_cur(task, RLIMIT_MEMLOCK))
return -ENOMEM;
/*
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 92ed83f..ad663c8 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -129,7 +129,7 @@ ia64_brk (unsigned long brk)
goto out;
/* Check against rlimit.. */
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+ rlim = rlim_get_cur(RLIMIT_DATA);
if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
goto out;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 1857766..0995019 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -91,7 +91,7 @@ dma_mark_clean(void *addr, size_t size)
inline void
ia64_set_rbs_bot (void)
{
- unsigned long stack_size = current->signal->rlim[RLIMIT_STACK].rlim_max & -16;
+ unsigned long stack_size = rlim_get_max(RLIMIT_STACK) & -16;
if (stack_size > MAX_USER_STACK_SIZE)
stack_size = MAX_USER_STACK_SIZE;
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 16/27] PPC: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (13 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 15/27] IA64: use helpers for rlimits Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-28 0:19 ` Benjamin Herrenschmidt
2009-11-27 23:05 ` [PATCH v3 17/27] S390: " Jiri Slaby
` (11 subsequent siblings)
26 siblings, 1 reply; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Benjamin Herrenschmidt, Paul Mackerras, linuxppc-dev
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
arch/powerpc/mm/mmap_64.c | 4 ++--
arch/powerpc/platforms/cell/spufs/coredump.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/mm/mmap_64.c b/arch/powerpc/mm/mmap_64.c
index 0d957a4..8df1299 100644
--- a/arch/powerpc/mm/mmap_64.c
+++ b/arch/powerpc/mm/mmap_64.c
@@ -47,7 +47,7 @@ static inline int mmap_is_legacy(void)
if (current->personality & ADDR_COMPAT_LAYOUT)
return 1;
- if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+ if (rlim_get_cur(RLIMIT_STACK) == RLIM_INFINITY)
return 1;
return sysctl_legacy_va_layout;
@@ -77,7 +77,7 @@ static unsigned long mmap_rnd(void)
static inline unsigned long mmap_base(void)
{
- unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+ unsigned long gap = rlim_get_cur(RLIMIT_STACK);
if (gap < MIN_GAP)
gap = MIN_GAP;
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index c4d4a19..4ef1c92 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -54,7 +54,7 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer,
*/
static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset)
{
- unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
+ unsigned long limit = rlim_get_cur(RLIMIT_CORE);
ssize_t written;
if (*foffset + nr > limit)
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH v3 16/27] PPC: use helpers for rlimits
2009-11-27 23:05 ` [PATCH v3 16/27] PPC: " Jiri Slaby
@ 2009-11-28 0:19 ` Benjamin Herrenschmidt
2009-11-28 8:47 ` Jiri Slaby
0 siblings, 1 reply; 34+ messages in thread
From: Benjamin Herrenschmidt @ 2009-11-28 0:19 UTC (permalink / raw)
To: Jiri Slaby
Cc: jirislaby, mingo, nhorman, sfr, linux-kernel, akpm,
marcin.slusarz, tglx, mingo, hpa, torvalds, oleg, James Morris,
Heiko Carstens, Paul Mackerras, linuxppc-dev
On Sat, 2009-11-28 at 00:05 +0100, Jiri Slaby wrote:
> Make sure compiler won't do weird things with limits. E.g. fetching
> them twice may return 2 different values after writable limits are
> implemented.
>
> I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
> applicable.
Thanks. I have that already queued up.
Cheers,
Ben.
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: James Morris <jmorris@namei.org>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@ozlabs.org
> ---
> arch/powerpc/mm/mmap_64.c | 4 ++--
> arch/powerpc/platforms/cell/spufs/coredump.c | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/mm/mmap_64.c b/arch/powerpc/mm/mmap_64.c
> index 0d957a4..8df1299 100644
> --- a/arch/powerpc/mm/mmap_64.c
> +++ b/arch/powerpc/mm/mmap_64.c
> @@ -47,7 +47,7 @@ static inline int mmap_is_legacy(void)
> if (current->personality & ADDR_COMPAT_LAYOUT)
> return 1;
>
> - if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
> + if (rlim_get_cur(RLIMIT_STACK) == RLIM_INFINITY)
> return 1;
>
> return sysctl_legacy_va_layout;
> @@ -77,7 +77,7 @@ static unsigned long mmap_rnd(void)
>
> static inline unsigned long mmap_base(void)
> {
> - unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
> + unsigned long gap = rlim_get_cur(RLIMIT_STACK);
>
> if (gap < MIN_GAP)
> gap = MIN_GAP;
> diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
> index c4d4a19..4ef1c92 100644
> --- a/arch/powerpc/platforms/cell/spufs/coredump.c
> +++ b/arch/powerpc/platforms/cell/spufs/coredump.c
> @@ -54,7 +54,7 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer,
> */
> static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset)
> {
> - unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
> + unsigned long limit = rlim_get_cur(RLIMIT_CORE);
> ssize_t written;
>
> if (*foffset + nr > limit)
^ permalink raw reply [flat|nested] 34+ messages in thread* Re: [PATCH v3 16/27] PPC: use helpers for rlimits
2009-11-28 0:19 ` Benjamin Herrenschmidt
@ 2009-11-28 8:47 ` Jiri Slaby
2009-11-28 21:16 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 34+ messages in thread
From: Jiri Slaby @ 2009-11-28 8:47 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Paul Mackerras, linuxppc-dev
On 11/28/2009 01:19 AM, Benjamin Herrenschmidt wrote:
> On Sat, 2009-11-28 at 00:05 +0100, Jiri Slaby wrote:
>> Make sure compiler won't do weird things with limits. E.g. fetching
>> them twice may return 2 different values after writable limits are
>> implemented.
>>
>> I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
>> applicable.
>
> Thanks. I have that already queued up.
Are you sure? The previous version with ACCESS_ONCE was generally
NACKed. This one uses a newly added helper which is much more cleaner
way to do it.
thanks,
--
js
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 16/27] PPC: use helpers for rlimits
2009-11-28 8:47 ` Jiri Slaby
@ 2009-11-28 21:16 ` Benjamin Herrenschmidt
2009-11-29 11:06 ` Stephen Rothwell
0 siblings, 1 reply; 34+ messages in thread
From: Benjamin Herrenschmidt @ 2009-11-28 21:16 UTC (permalink / raw)
To: Jiri Slaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Paul Mackerras, linuxppc-dev
On Sat, 2009-11-28 at 09:47 +0100, Jiri Slaby wrote:
> Are you sure? The previous version with ACCESS_ONCE was generally
> NACKed. This one uses a newly added helper which is much more cleaner
> way to do it.
I haven't seen a nack, but then I haven't pushed out yet so I can easily
back it off and replace it with this one.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 16/27] PPC: use helpers for rlimits
2009-11-28 21:16 ` Benjamin Herrenschmidt
@ 2009-11-29 11:06 ` Stephen Rothwell
0 siblings, 0 replies; 34+ messages in thread
From: Stephen Rothwell @ 2009-11-29 11:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Jiri Slaby, mingo, nhorman, linux-kernel, akpm, marcin.slusarz,
tglx, mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Paul Mackerras, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 750 bytes --]
Hi Ben,
On Sun, 29 Nov 2009 08:16:03 +1100 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> On Sat, 2009-11-28 at 09:47 +0100, Jiri Slaby wrote:
> > Are you sure? The previous version with ACCESS_ONCE was generally
> > NACKed. This one uses a newly added helper which is much more cleaner
> > way to do it.
>
> I haven't seen a nack, but then I haven't pushed out yet so I can easily
> back it off and replace it with this one.
You need to hold off adding this to your tree until after patch 14/27
("resource: add helpers for fetching rlimits") of this series (or a
modified version of it) reaches Linus' tree.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v3 17/27] S390: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (14 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 16/27] PPC: " Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 18/27] SPARC: " Jiri Slaby
` (10 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Martin Schwidefsky, linux390, linux-s390
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
arch/s390/mm/mmap.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index f4558cc..0acf3aa 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -40,7 +40,7 @@
static inline unsigned long mmap_base(void)
{
- unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+ unsigned long gap = rlim_get_cur(RLIMIT_STACK);
if (gap < MIN_GAP)
gap = MIN_GAP;
@@ -61,7 +61,7 @@ static inline int mmap_is_legacy(void)
#endif
return sysctl_legacy_va_layout ||
(current->personality & ADDR_COMPAT_LAYOUT) ||
- current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY;
+ rlim_get_cur(RLIMIT_STACK) == RLIM_INFINITY;
}
#ifndef CONFIG_64BIT
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 18/27] SPARC: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (15 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 17/27] S390: " Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:05 ` [PATCH v3 19/27] X86: " Jiri Slaby
` (9 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
David S. Miller, sparclinux
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
---
arch/sparc/kernel/sys_sparc_64.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index e2d1024..d53870c 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -361,6 +361,7 @@ EXPORT_SYMBOL(get_fb_unmapped_area);
void arch_pick_mmap_layout(struct mm_struct *mm)
{
unsigned long random_factor = 0UL;
+ unsigned long gap;
if (current->flags & PF_RANDOMIZE) {
random_factor = get_random_int();
@@ -375,9 +376,10 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
* Fall back to the standard layout if the personality
* bit is set, or if the expected stack growth is unlimited:
*/
+ gap = rlim_get_cur(RLIMIT_STACK);
if (!test_thread_flag(TIF_32BIT) ||
(current->personality & ADDR_COMPAT_LAYOUT) ||
- current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
+ gap == RLIM_INFINITY ||
sysctl_legacy_va_layout) {
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
mm->get_unmapped_area = arch_get_unmapped_area;
@@ -385,9 +387,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
} else {
/* We know it's 32-bit */
unsigned long task_size = STACK_TOP32;
- unsigned long gap;
- gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
if (gap < 128 * 1024 * 1024)
gap = 128 * 1024 * 1024;
if (gap > (task_size / 6 * 5))
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 19/27] X86: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (16 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 18/27] SPARC: " Jiri Slaby
@ 2009-11-27 23:05 ` Jiri Slaby
2009-11-27 23:06 ` [PATCH v3 20/27] FS: " Jiri Slaby
` (8 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:05 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens, x86
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
---
arch/x86/ia32/ia32_aout.c | 2 +-
arch/x86/mm/mmap.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
index 2a4d073..d311ec5 100644
--- a/arch/x86/ia32/ia32_aout.c
+++ b/arch/x86/ia32/ia32_aout.c
@@ -297,7 +297,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
* size limits imposed on them by creating programs with large
* arrays in the data or bss.
*/
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+ rlim = rlim_get_cur(RLIMIT_DATA);
if (rlim >= RLIM_INFINITY)
rlim = ~0;
if (ex.a_data + ex.a_bss > rlim)
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index c8191de..6677bf0 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -71,7 +71,7 @@ static int mmap_is_legacy(void)
if (current->personality & ADDR_COMPAT_LAYOUT)
return 1;
- if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+ if (rlim_get_cur(RLIMIT_STACK) == RLIM_INFINITY)
return 1;
return sysctl_legacy_va_layout;
@@ -96,7 +96,7 @@ static unsigned long mmap_rnd(void)
static unsigned long mmap_base(void)
{
- unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+ unsigned long gap = rlim_get_cur(RLIMIT_STACK);
if (gap < MIN_GAP)
gap = MIN_GAP;
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 20/27] FS: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (17 preceding siblings ...)
2009-11-27 23:05 ` [PATCH v3 19/27] X86: " Jiri Slaby
@ 2009-11-27 23:06 ` Jiri Slaby
2009-11-27 23:06 ` [PATCH v3 21/27] MM: " Jiri Slaby
` (7 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:06 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Alexander Viro, linux-fsdevel
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
---
fs/attr.c | 2 +-
fs/binfmt_aout.c | 2 +-
fs/binfmt_flat.c | 2 +-
fs/exec.c | 8 ++++----
fs/fcntl.c | 2 +-
fs/file.c | 2 +-
fs/proc/array.c | 4 ++--
fs/select.c | 2 +-
8 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/fs/attr.c b/fs/attr.c
index 96d394b..3554042 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -82,7 +82,7 @@ int inode_newsize_ok(const struct inode *inode, loff_t offset)
if (inode->i_size < offset) {
unsigned long limit;
- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+ limit = rlim_get_cur(RLIMIT_FSIZE);
if (limit != RLIM_INFINITY && offset > limit)
goto out_sig;
if (offset > inode->i_sb->s_maxbytes)
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index b639dcf..dc3f316 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -246,7 +246,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
* size limits imposed on them by creating programs with large
* arrays in the data or bss.
*/
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+ rlim = rlim_get_cur(RLIMIT_DATA);
if (rlim >= RLIM_INFINITY)
rlim = ~0;
if (ex.a_data + ex.a_bss > rlim)
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index a279665..0161f3c 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -501,7 +501,7 @@ static int load_flat_file(struct linux_binprm * bprm,
* size limits imposed on them by creating programs with large
* arrays in the data or bss.
*/
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+ rlim = rlim_get_cur(RLIMIT_DATA);
if (rlim >= RLIM_INFINITY)
rlim = ~0;
if (data_len + bss_len > rlim) {
diff --git a/fs/exec.c b/fs/exec.c
index ba112bd..08dd798 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -196,7 +196,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
* to work from.
*/
rlim = current->signal->rlim;
- if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
+ if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
put_page(page);
return NULL;
}
@@ -575,7 +575,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
#ifdef CONFIG_STACK_GROWSUP
/* Limit stack size to 1GB */
- stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max;
+ stack_base = rlim_get_max(RLIMIT_STACK);
if (stack_base > (1 << 30))
stack_base = 1 << 30;
@@ -1503,7 +1503,7 @@ static int format_corename(char *corename, long signr)
/* core limit size */
case 'c':
rc = snprintf(out_ptr, out_end - out_ptr,
- "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur);
+ "%lu", rlim_get_cur(RLIMIT_CORE));
if (rc > out_end - out_ptr)
goto out;
out_ptr += rc;
@@ -1762,7 +1762,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
int retval = 0;
int flag = 0;
int ispipe = 0;
- unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
+ unsigned long core_limit = rlim_get_cur(RLIMIT_CORE);
char **helper_argv = NULL;
int helper_argc = 0;
int dump_count = 0;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 2cf93ec..8dd4b4f 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -344,7 +344,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
switch (cmd) {
case F_DUPFD:
case F_DUPFD_CLOEXEC:
- if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+ if (arg >= rlim_get_cur(RLIMIT_NOFILE))
break;
err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
if (err >= 0) {
diff --git a/fs/file.c b/fs/file.c
index 87e1290..0a472ff 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -257,7 +257,7 @@ int expand_files(struct files_struct *files, int nr)
* N.B. For clone tasks sharing a files structure, this test
* will limit the total number of files that can be opened.
*/
- if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+ if (nr >= rlim_get_cur(RLIMIT_NOFILE))
return -EMFILE;
/* Do we need to expand? */
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 822c2d5..54ba2d6 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -266,7 +266,7 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
collect_sigign_sigcatch(p, &ignored, &caught);
num_threads = atomic_read(&p->signal->count);
qsize = atomic_read(&__task_cred(p)->user->sigpending);
- qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
+ qlim = task_rlim_get_cur(p, RLIMIT_SIGPENDING);
unlock_task_sighand(p, &flags);
}
@@ -491,7 +491,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
cutime = sig->cutime;
cstime = sig->cstime;
cgtime = sig->cgtime;
- rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
+ rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
/* add up live thread stats at the group level */
if (whole) {
diff --git a/fs/select.c b/fs/select.c
index fd38ce2..ab34a88 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -821,7 +821,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
struct poll_list *walk = head;
unsigned long todo = nfds;
- if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+ if (nfds > rlim_get_cur(RLIMIT_NOFILE))
return -EINVAL;
len = min_t(unsigned int, nfds, N_STACK_PPS);
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 21/27] MM: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (18 preceding siblings ...)
2009-11-27 23:06 ` [PATCH v3 20/27] FS: " Jiri Slaby
@ 2009-11-27 23:06 ` Jiri Slaby
2009-11-27 23:06 ` [PATCH v3 22/27] core: " Jiri Slaby
` (6 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:06 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
linux-mm
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: linux-mm@kvack.org
---
mm/filemap.c | 2 +-
mm/mlock.c | 12 ++++++------
mm/mmap.c | 13 +++++++------
mm/mremap.c | 2 +-
4 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index ef169f3..8896396 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1971,7 +1971,7 @@ EXPORT_SYMBOL(iov_iter_single_seg_count);
inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk)
{
struct inode *inode = file->f_mapping->host;
- unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+ unsigned long limit = rlim_get_cur(RLIMIT_FSIZE);
if (unlikely(*pos < 0))
return -EINVAL;
diff --git a/mm/mlock.c b/mm/mlock.c
index bd6f0e4..a8ee8bf 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -25,7 +25,7 @@ int can_do_mlock(void)
{
if (capable(CAP_IPC_LOCK))
return 1;
- if (current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur != 0)
+ if (rlim_get_cur(RLIMIT_MEMLOCK) != 0)
return 1;
return 0;
}
@@ -490,7 +490,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
locked = len >> PAGE_SHIFT;
locked += current->mm->locked_vm;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
/* check against resource limits */
@@ -553,7 +553,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
down_write(¤t->mm->mmap_sem);
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
ret = -ENOMEM;
@@ -587,7 +587,7 @@ int user_shm_lock(size_t size, struct user_struct *user)
int allowed = 0;
locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
if (lock_limit == RLIM_INFINITY)
allowed = 1;
lock_limit >>= PAGE_SHIFT;
@@ -621,12 +621,12 @@ int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
down_write(&mm->mmap_sem);
- lim = rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
+ lim = ACCESS_ONCE(rlim[RLIMIT_AS].rlim_cur) >> PAGE_SHIFT;
vm = mm->total_vm + pgsz;
if (lim < vm)
goto out;
- lim = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+ lim = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur) >> PAGE_SHIFT;
vm = mm->locked_vm + pgsz;
if (lim < vm)
goto out;
diff --git a/mm/mmap.c b/mm/mmap.c
index 73f5e4b..dc49f43 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -266,7 +266,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
* segment grow beyond its set limit the in case where the limit is
* not page aligned -Ram Gupta
*/
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+ rlim = rlim_get_cur(RLIMIT_DATA);
if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
(mm->end_data - mm->start_data) > rlim)
goto out;
@@ -990,7 +990,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long locked, lock_limit;
locked = len >> PAGE_SHIFT;
locked += mm->locked_vm;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
return -EAGAIN;
@@ -1565,7 +1565,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
return -ENOMEM;
/* Stack limit test */
- if (size > rlim[RLIMIT_STACK].rlim_cur)
+ if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
return -ENOMEM;
/* mlock limit tests */
@@ -1573,7 +1573,8 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
unsigned long locked;
unsigned long limit;
locked = mm->locked_vm + grow;
- limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+ limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur);
+ limit >>= PAGE_SHIFT;
if (locked > limit && !capable(CAP_IPC_LOCK))
return -ENOMEM;
}
@@ -2026,7 +2027,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
unsigned long locked, lock_limit;
locked = len >> PAGE_SHIFT;
locked += mm->locked_vm;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
return -EAGAIN;
@@ -2240,7 +2241,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
unsigned long cur = mm->total_vm; /* pages */
unsigned long lim;
- lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
+ lim = rlim_get_cur(RLIMIT_AS) >> PAGE_SHIFT;
if (cur + npages > lim)
return 0;
diff --git a/mm/mremap.c b/mm/mremap.c
index 97bff25..00a384c 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -358,7 +358,7 @@ unsigned long do_mremap(unsigned long addr,
if (vma->vm_flags & VM_LOCKED) {
unsigned long locked, lock_limit;
locked = mm->locked_vm << PAGE_SHIFT;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
locked += new_len - old_len;
ret = -EAGAIN;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 22/27] core: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (19 preceding siblings ...)
2009-11-27 23:06 ` [PATCH v3 21/27] MM: " Jiri Slaby
@ 2009-11-27 23:06 ` Jiri Slaby
2009-11-27 23:06 ` [PATCH v3 23/27] misc: " Jiri Slaby
` (5 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:06 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Peter Zijlstra
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
---
kernel/fork.c | 10 ++++++----
kernel/perf_event.c | 2 +-
kernel/posix-cpu-timers.c | 16 +++++++++-------
kernel/sched.c | 4 ++--
kernel/sched_rt.c | 5 +++--
kernel/signal.c | 2 +-
kernel/sys.c | 3 +--
7 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index 166b8c4..9f0773d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -822,6 +822,8 @@ void __cleanup_sighand(struct sighand_struct *sighand)
*/
static void posix_cpu_timers_init_group(struct signal_struct *sig)
{
+ unsigned long cpu_limit;
+
/* Thread group counters. */
thread_group_cputime_init(sig);
@@ -836,9 +838,9 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
sig->cputime_expires.virt_exp = cputime_zero;
sig->cputime_expires.sched_exp = 0;
- if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
- sig->cputime_expires.prof_exp =
- secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
+ cpu_limit = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
+ if (cpu_limit != RLIM_INFINITY) {
+ sig->cputime_expires.prof_exp = secs_to_cputime(cpu_limit);
sig->cputimer.running = 1;
}
@@ -1028,7 +1030,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
#endif
retval = -EAGAIN;
if (atomic_read(&p->real_cred->user->processes) >=
- p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
+ task_rlim_get_cur(p, RLIMIT_NPROC)) {
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
p->real_cred->user != INIT_USER)
goto bad_fork_free;
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 7f29643..02ba1e0 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -2420,7 +2420,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
if (user_locked > user_lock_limit)
extra = user_locked - user_lock_limit;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
locked = vma->vm_mm->locked_vm + extra;
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index a7dcce1..79d4cb3 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -640,7 +640,7 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
if (expires_le(sig->it[CPUCLOCK_PROF].expires,
exp->cpu))
break;
- i = sig->rlim[RLIMIT_CPU].rlim_cur;
+ i = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
if (i != RLIM_INFINITY &&
i <= cputime_to_secs(exp->cpu))
break;
@@ -1032,9 +1032,10 @@ static void check_thread_timers(struct task_struct *tsk,
/*
* Check for the special case thread timers.
*/
- soft = sig->rlim[RLIMIT_RTTIME].rlim_cur;
+ soft = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur);
if (soft != RLIM_INFINITY) {
- unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max;
+ unsigned long hard = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].
+ rlim_max);
if (hard != RLIM_INFINITY &&
tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
@@ -1122,7 +1123,7 @@ static void check_process_timers(struct task_struct *tsk,
unsigned long long sum_sched_runtime, sched_expires;
struct list_head *timers = sig->cpu_timers;
struct task_cputime cputime;
- unsigned long cpu_cur_lim = sig->rlim[RLIMIT_CPU].rlim_cur;
+ unsigned long cpu_cur_lim = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
/*
* Don't sample the current process CPU clocks if there are no timers.
@@ -1198,7 +1199,8 @@ static void check_process_timers(struct task_struct *tsk,
if (cpu_cur_lim != RLIM_INFINITY) {
unsigned long psecs = cputime_to_secs(ptime);
- unsigned long hard = sig->rlim[RLIMIT_CPU].rlim_max;
+ unsigned long hard =
+ ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max);
cputime_t x;
if (psecs >= hard) {
/*
@@ -1385,7 +1387,7 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
return 1;
}
- return sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY;
+ return ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur) != RLIM_INFINITY;
}
/*
@@ -1483,7 +1485,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
* If the RLIMIT_CPU timer will expire before the
* ITIMER_PROF timer, we have nothing else to do.
*/
- if (tsk->signal->rlim[RLIMIT_CPU].rlim_cur
+ if (task_rlim_get_cur(tsk, RLIMIT_CPU)
< cputime_to_secs(*newval))
return;
}
diff --git a/kernel/sched.c b/kernel/sched.c
index 3c11ae0..0e4077d 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6072,7 +6072,7 @@ int can_nice(const struct task_struct *p, const int nice)
/* convert nice value [19,-20] to rlimit style value [1,40] */
int nice_rlim = 20 - nice;
- return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur ||
+ return (nice_rlim <= task_rlim_get_cur(p, RLIMIT_NICE) ||
capable(CAP_SYS_NICE));
}
@@ -6257,7 +6257,7 @@ recheck:
if (!lock_task_sighand(p, &flags))
return -ESRCH;
- rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur;
+ rlim_rtprio = task_rlim_get_cur(p, RLIMIT_RTPRIO);
unlock_task_sighand(p, &flags);
/* can't set/change the rt policy */
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index a4d790c..ab41715 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -1683,8 +1683,9 @@ static void watchdog(struct rq *rq, struct task_struct *p)
if (!p->signal)
return;
- soft = p->signal->rlim[RLIMIT_RTTIME].rlim_cur;
- hard = p->signal->rlim[RLIMIT_RTTIME].rlim_max;
+ /* max may change after cur was read, this will be fixed next tick */
+ soft = task_rlim_get_cur(p, RLIMIT_RTTIME);
+ hard = task_rlim_get_max(p, RLIMIT_RTTIME);
if (soft != RLIM_INFINITY) {
unsigned long next;
diff --git a/kernel/signal.c b/kernel/signal.c
index 6705320..34efd79 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -209,7 +209,7 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
atomic_inc(&user->sigpending);
if (override_rlimit ||
atomic_read(&user->sigpending) <=
- t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
+ task_rlim_get_cur(t, RLIMIT_SIGPENDING))
q = kmem_cache_alloc(sigqueue_cachep, flags);
if (unlikely(q == NULL)) {
atomic_dec(&user->sigpending);
diff --git a/kernel/sys.c b/kernel/sys.c
index fad6010..c4065c5 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -572,8 +572,7 @@ static int set_user(struct cred *new)
return -EINVAL;
}
- if (atomic_read(&new_user->processes) >=
- current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
+ if (atomic_read(&new_user->processes) >= rlim_get_cur(RLIMIT_NPROC) &&
new_user != INIT_USER) {
free_uid(new_user);
return -EAGAIN;
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 23/27] misc: use helpers for rlimits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (20 preceding siblings ...)
2009-11-27 23:06 ` [PATCH v3 22/27] core: " Jiri Slaby
@ 2009-11-27 23:06 ` Jiri Slaby
2009-12-09 23:59 ` Roland Dreier
2009-11-27 23:06 ` [PATCH v3 24/27] core: implement getprlimit and setprlimit syscalls Jiri Slaby
` (4 subsequent siblings)
26 siblings, 1 reply; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:06 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens,
Roland Dreier, Sean Hefty, Hal Rosenstock, linux-rdma
Make sure compiler won't do weird things with limits. E.g. fetching
them twice may return 2 different values after writable limits are
implemented.
I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
applicable.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Roland Dreier <rolandd@cisco.com>
Cc: Sean Hefty <sean.hefty@intel.com>
Cc: Hal Rosenstock <hal.rosenstock@gmail.com>
Cc: linux-rdma@vger.kernel.org
---
drivers/infiniband/core/umem.c | 2 +-
drivers/infiniband/hw/ipath/ipath_user_pages.c | 3 +--
ipc/mqueue.c | 2 +-
ipc/shm.c | 3 +--
4 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 6f7c096..2a8338a 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -136,7 +136,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
down_write(¤t->mm->mmap_sem);
locked = npages + current->mm->locked_vm;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
ret = -ENOMEM;
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index 82878e3..431ec61 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -59,8 +59,7 @@ static int __get_user_pages(unsigned long start_page, size_t num_pages,
size_t got;
int ret;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
- PAGE_SHIFT;
+ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
if (num_pages > lock_limit) {
ret = -ENOMEM;
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index ee9d697..0e18cde 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -153,7 +153,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
spin_lock(&mq_lock);
if (u->mq_bytes + mq_bytes < u->mq_bytes ||
u->mq_bytes + mq_bytes >
- p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
+ task_rlim_get_cur(p, RLIMIT_MSGQUEUE)) {
spin_unlock(&mq_lock);
goto out_inode;
}
diff --git a/ipc/shm.c b/ipc/shm.c
index 464694e..abd1ebd 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -761,8 +761,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
if (euid != shp->shm_perm.uid &&
euid != shp->shm_perm.cuid)
goto out_unlock;
- if (cmd == SHM_LOCK &&
- !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
+ if (cmd == SHM_LOCK && !rlim_get_cur(RLIMIT_MEMLOCK))
goto out_unlock;
}
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH v3 23/27] misc: use helpers for rlimits
2009-11-27 23:06 ` [PATCH v3 23/27] misc: " Jiri Slaby
@ 2009-12-09 23:59 ` Roland Dreier
0 siblings, 0 replies; 34+ messages in thread
From: Roland Dreier @ 2009-12-09 23:59 UTC (permalink / raw)
To: Jiri Slaby
Cc: jirislaby, mingo, nhorman, sfr, linux-kernel, akpm,
marcin.slusarz, tglx, mingo, hpa, torvalds, oleg, James Morris,
Heiko Carstens, Roland Dreier, Sean Hefty, Hal Rosenstock,
linux-rdma
Not sure it matters at this part, but for the drivers/infiniband part,
you can add:
Acked-by: Roland Dreier <rolandd@cisco.com>
wrapping all the current->signal->rlim[] stuff in a helper function
looks like a nice cleanup independent of the writable limit stuff.
- R.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v3 24/27] core: implement getprlimit and setprlimit syscalls
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (21 preceding siblings ...)
2009-11-27 23:06 ` [PATCH v3 23/27] misc: " Jiri Slaby
@ 2009-11-27 23:06 ` Jiri Slaby
2009-11-27 23:06 ` [PATCH v3 25/27] unistd: add __NR_[get|set]prlimit syscall numbers Jiri Slaby
` (3 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:06 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens
This patch adds the code to support the sys_setprlimit and set_getprlimit
syscalls which modify the rlim values of a selected process.
All rlim users now either use newly added accessors or doesn't need them
due to
- locking
- a process was just forked and nobody else knows about it yet (and
nobody can't thus read/write limits)
Based on Neil's work. Thank him.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
---
include/linux/syscalls.h | 4 ++
kernel/sys.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a990ace..6fd7ba6 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -702,11 +702,15 @@ asmlinkage long sys_newuname(struct new_utsname __user *name);
asmlinkage long sys_getrlimit(unsigned int resource,
struct rlimit __user *rlim);
+asmlinkage long sys_getprlimit(pid_t pid, unsigned int resource,
+ struct rlimit __user *rlim);
#if defined(COMPAT_RLIM_OLD_INFINITY) || !(defined(CONFIG_IA64))
asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim);
#endif
asmlinkage long sys_setrlimit(unsigned int resource,
struct rlimit __user *rlim);
+asmlinkage long sys_setprlimit(pid_t pid, unsigned int resource,
+ struct rlimit __user *rlim);
asmlinkage long sys_getrusage(int who, struct rusage __user *ru);
asmlinkage long sys_umask(int mask);
diff --git a/kernel/sys.c b/kernel/sys.c
index c4065c5..626148f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1212,6 +1212,61 @@ SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim)
}
}
+static int check_prlimit_permission(struct task_struct *task)
+{
+ const struct cred *cred = current_cred(), *tcred;
+ int ret = 0;
+
+ rcu_read_lock();
+ tcred = __task_cred(task);
+ if ((cred->uid != tcred->euid ||
+ cred->uid != tcred->suid ||
+ cred->uid != tcred->uid ||
+ cred->gid != tcred->egid ||
+ cred->gid != tcred->sgid ||
+ cred->gid != tcred->gid) &&
+ !capable(CAP_SYS_RESOURCE)) {
+ ret = -EPERM;
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
+SYSCALL_DEFINE3(getprlimit, pid_t, pid, unsigned int, resource,
+ struct rlimit __user *, rlim)
+{
+ struct rlimit val;
+ struct task_struct *tsk;
+ int ret;
+
+ if (resource >= RLIM_NLIMITS)
+ return -EINVAL;
+
+ read_lock(&tasklist_lock);
+
+ tsk = find_task_by_vpid(pid);
+ if (!tsk || !tsk->sighand) {
+ ret = -ESRCH;
+ goto err_unlock;
+ }
+
+ ret = check_prlimit_permission(tsk);
+ if (ret)
+ goto err_unlock;
+
+ task_lock(tsk->group_leader);
+ val = tsk->signal->rlim[resource];
+ task_unlock(tsk->group_leader);
+
+ read_unlock(&tasklist_lock);
+
+ return copy_to_user(rlim, &val, sizeof(*rlim)) ? -EFAULT : 0;
+err_unlock:
+ read_unlock(&tasklist_lock);
+ return ret;
+}
+
+
#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
/*
@@ -1310,6 +1365,37 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
return do_setrlimit(current, resource, &new_rlim);
}
+SYSCALL_DEFINE3(setprlimit, pid_t, pid, unsigned int, resource,
+ struct rlimit __user *, rlim)
+{
+ struct task_struct *tsk;
+ struct rlimit new_rlim;
+ int ret;
+
+ if (resource >= RLIM_NLIMITS)
+ return -EINVAL;
+
+ if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
+ return -EFAULT;
+
+ rcu_read_lock();
+ tsk = find_task_by_vpid(pid);
+ if (!tsk) {
+ rcu_read_unlock();
+ return -ESRCH;
+ }
+ get_task_struct(tsk);
+ rcu_read_unlock();
+
+ ret = check_prlimit_permission(tsk);
+ if (!ret)
+ ret = do_setrlimit(tsk, resource, &new_rlim);
+
+ put_task_struct(tsk);
+
+ return ret;
+}
+
/*
* It would make sense to put struct rusage in the task_struct,
* except that would make the task_struct be *really big*. After
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 25/27] unistd: add __NR_[get|set]prlimit syscall numbers
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (22 preceding siblings ...)
2009-11-27 23:06 ` [PATCH v3 24/27] core: implement getprlimit and setprlimit syscalls Jiri Slaby
@ 2009-11-27 23:06 ` Jiri Slaby
2009-11-27 23:06 ` [PATCH v3 26/27] COMPAT: add get/put_compat_rlimit Jiri Slaby
` (2 subsequent siblings)
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:06 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens
From: Neil Horman <nhorman@tuxdriver.com>
Add __NR_[get|set]prlimit syscall numbers to asm-generic. Add them
also to asm-x86.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
---
arch/x86/include/asm/unistd_32.h | 4 +++-
arch/x86/include/asm/unistd_64.h | 4 ++++
arch/x86/kernel/syscall_table_32.S | 2 ++
include/asm-generic/unistd.h | 6 +++++-
4 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index 6fb3c20..06dbb34 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -342,10 +342,12 @@
#define __NR_pwritev 334
#define __NR_rt_tgsigqueueinfo 335
#define __NR_perf_event_open 336
+#define __NR_getprlimit 337
+#define __NR_setprlimit 338
#ifdef __KERNEL__
-#define NR_syscalls 337
+#define NR_syscalls 339
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index 8d3ad0a..48ea56c 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -661,6 +661,10 @@ __SYSCALL(__NR_pwritev, sys_pwritev)
__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
#define __NR_perf_event_open 298
__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
+#define __NR_getprlimit 299
+__SYSCALL(__NR_getprlimit, sys_getprlimit)
+#define __NR_setprlimit 300
+__SYSCALL(__NR_setprlimit, sys_setprlimit)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index 0157cd2..2dd45cd 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -336,3 +336,5 @@ ENTRY(sys_call_table)
.long sys_pwritev
.long sys_rt_tgsigqueueinfo /* 335 */
.long sys_perf_event_open
+ .long sys_getprlimit
+ .long sys_setprlimit
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h
index d76b66a..950587d 100644
--- a/include/asm-generic/unistd.h
+++ b/include/asm-generic/unistd.h
@@ -622,9 +622,13 @@ __SYSCALL(__NR_move_pages, sys_move_pages)
__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
#define __NR_perf_event_open 241
__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
+#define __NR_getprlimit 242
+__SYSCALL(__NR_getprlimit, sys_getprlimit)
+#define __NR_setprlimit 243
+__SYSCALL(__NR_setprlimit, sys_setprlimit)
#undef __NR_syscalls
-#define __NR_syscalls 242
+#define __NR_syscalls 244
/*
* All syscalls below here should go away really,
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 26/27] COMPAT: add get/put_compat_rlimit
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (23 preceding siblings ...)
2009-11-27 23:06 ` [PATCH v3 25/27] unistd: add __NR_[get|set]prlimit syscall numbers Jiri Slaby
@ 2009-11-27 23:06 ` Jiri Slaby
2009-11-27 23:06 ` [PATCH v3 27/27] x86: add ia32 compat prlimit syscalls Jiri Slaby
2009-11-27 23:41 ` [PATCH v3 00/27] writable limits Jiri Slaby
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:06 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens
Extract those functions from compat_sys_[gs]etrlimit for later
use with newly added rlimit syscalls.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
---
kernel/compat.c | 61 ++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 40 insertions(+), 21 deletions(-)
diff --git a/kernel/compat.c b/kernel/compat.c
index f6c204f..af15719 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -274,6 +274,39 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
return ret;
}
+static int get_compat_rlimit(struct rlimit *dst,
+ const struct compat_rlimit __user *src)
+{
+ if (!access_ok(VERIFY_READ, src, sizeof(*src)) ||
+ __get_user(dst->rlim_cur, &src->rlim_cur) ||
+ __get_user(dst->rlim_max, &src->rlim_max))
+ return -EFAULT;
+
+ if (dst->rlim_cur == COMPAT_RLIM_INFINITY)
+ dst->rlim_cur = RLIM_INFINITY;
+ if (dst->rlim_max == COMPAT_RLIM_INFINITY)
+ dst->rlim_max = RLIM_INFINITY;
+ return 0;
+}
+
+static int put_compat_rlimit(const struct rlimit *src,
+ struct compat_rlimit __user *dst)
+{
+ struct rlimit r = *src;
+
+ if (r.rlim_cur > COMPAT_RLIM_INFINITY)
+ r.rlim_cur = COMPAT_RLIM_INFINITY;
+ if (r.rlim_max > COMPAT_RLIM_INFINITY)
+ r.rlim_max = COMPAT_RLIM_INFINITY;
+
+ if (!access_ok(VERIFY_WRITE, dst, sizeof(*dst)) ||
+ __put_user(r.rlim_cur, &dst->rlim_cur) ||
+ __put_user(r.rlim_max, &dst->rlim_max))
+ return -EFAULT;
+
+ return 0;
+}
+
asmlinkage long compat_sys_setrlimit(unsigned int resource,
struct compat_rlimit __user *rlim)
{
@@ -284,17 +317,12 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource,
if (resource >= RLIM_NLIMITS)
return -EINVAL;
- if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
- __get_user(r.rlim_cur, &rlim->rlim_cur) ||
- __get_user(r.rlim_max, &rlim->rlim_max))
- return -EFAULT;
+ ret = get_compat_rlimit(&r, rlim);
+ if (ret)
+ return ret;
- if (r.rlim_cur == COMPAT_RLIM_INFINITY)
- r.rlim_cur = RLIM_INFINITY;
- if (r.rlim_max == COMPAT_RLIM_INFINITY)
- r.rlim_max = RLIM_INFINITY;
set_fs(KERNEL_DS);
- ret = sys_setrlimit(resource, (struct rlimit __user *) &r);
+ ret = sys_setrlimit(resource, (struct rlimit __force __user *)&r);
set_fs(old_fs);
return ret;
}
@@ -336,19 +364,10 @@ asmlinkage long compat_sys_getrlimit (unsigned int resource,
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = sys_getrlimit(resource, (struct rlimit __user *) &r);
+ ret = sys_getrlimit(resource, (struct rlimit __force __user *)&r);
set_fs(old_fs);
- if (!ret) {
- if (r.rlim_cur > COMPAT_RLIM_INFINITY)
- r.rlim_cur = COMPAT_RLIM_INFINITY;
- if (r.rlim_max > COMPAT_RLIM_INFINITY)
- r.rlim_max = COMPAT_RLIM_INFINITY;
-
- if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
- __put_user(r.rlim_cur, &rlim->rlim_cur) ||
- __put_user(r.rlim_max, &rlim->rlim_max))
- return -EFAULT;
- }
+ if (!ret)
+ ret = put_compat_rlimit(&r, rlim);
return ret;
}
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 27/27] x86: add ia32 compat prlimit syscalls
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (24 preceding siblings ...)
2009-11-27 23:06 ` [PATCH v3 26/27] COMPAT: add get/put_compat_rlimit Jiri Slaby
@ 2009-11-27 23:06 ` Jiri Slaby
2009-11-27 23:41 ` [PATCH v3 00/27] writable limits Jiri Slaby
26 siblings, 0 replies; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:06 UTC (permalink / raw)
To: jirislaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, James Morris, Heiko Carstens
To support 32/64-bit compatibility (rlimit structure contains 2 longs)
for prlimit syscalls, add compat wrappers for them.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: James Morris <jmorris@namei.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
---
arch/x86/ia32/ia32entry.S | 2 ++
kernel/compat.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 581b056..c61ced2 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -841,4 +841,6 @@ ia32_sys_call_table:
.quad compat_sys_pwritev
.quad compat_sys_rt_tgsigqueueinfo /* 335 */
.quad sys_perf_event_open
+ .quad compat_sys_getprlimit
+ .quad compat_sys_setprlimit
ia32_syscall_end:
diff --git a/kernel/compat.c b/kernel/compat.c
index af15719..c1d5704 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -371,6 +371,38 @@ asmlinkage long compat_sys_getrlimit (unsigned int resource,
return ret;
}
+asmlinkage long compat_sys_setprlimit(pid_t pid, unsigned int resource,
+ struct compat_rlimit __user *rlim)
+{
+ mm_segment_t old_fs = get_fs();
+ struct rlimit r;
+ int ret;
+
+ ret = get_compat_rlimit(&r, rlim);
+ if (ret)
+ return ret;
+
+ set_fs(KERNEL_DS);
+ ret = sys_setprlimit(pid, resource, (struct rlimit __force __user *)&r);
+ set_fs(old_fs);
+ return ret;
+}
+
+asmlinkage long compat_sys_getprlimit(pid_t pid, unsigned int resource,
+ struct compat_rlimit __user *rlim)
+{
+ mm_segment_t old_fs = get_fs();
+ struct rlimit r;
+ int ret;
+
+ set_fs(KERNEL_DS);
+ ret = sys_getprlimit(pid, resource, (struct rlimit __force __user *)&r);
+ set_fs(old_fs);
+ if (!ret)
+ ret = put_compat_rlimit(&r, rlim);
+ return ret;
+}
+
int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
{
if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
--
1.6.5.3
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH v3 00/27] writable limits
2009-11-27 23:05 [PATCH v3 01/27] SECURITY: selinux, fix update_rlimit_cpu parameter Jiri Slaby
` (25 preceding siblings ...)
2009-11-27 23:06 ` [PATCH v3 27/27] x86: add ia32 compat prlimit syscalls Jiri Slaby
@ 2009-11-27 23:41 ` Jiri Slaby
2009-11-28 7:28 ` Ingo Molnar
26 siblings, 1 reply; 34+ messages in thread
From: Jiri Slaby @ 2009-11-27 23:41 UTC (permalink / raw)
To: Jiri Slaby
Cc: mingo, nhorman, sfr, linux-kernel, akpm, marcin.slusarz, tglx,
mingo, hpa, torvalds, oleg, Stephen Smalley, Eric Paris,
David Howells
Hi,
I broke the threading to not mess up with the long thread.
In this version I got rid of the rlim access_only ugliness.
There are two things:
1)
<quote from=Ingo>
A prominent example would be the stack limit - we base address layout
decisions on it. Check arch/x86/mm/mmap.c. RLIM_INFINITY has a special
meaning plus we also set mmap_base() based on the rlim.
</quote>
Should there be some special handling of that? In standard setrlimit
there is none.
2)
<quote from=Oleg>
Hmm. you are right. Do you know why acct_file_reopen() does
if (old_acct)
do_acct_process();
???
</quote>
As I expressed myself before, I don't know why it is there (it doesn't
make sense to me either). But I took a look at when it was added. From
the very first merge of acct.c (2.1.68pre1) it was just in (name ==
NULL) path (turning acct off). Then in 2.1.126 it was switched to
account on every accounting file change.
I fear if we changed this, something would break.
thanks,
--
js
^ permalink raw reply [flat|nested] 34+ messages in thread* Re: [PATCH v3 00/27] writable limits
2009-11-27 23:41 ` [PATCH v3 00/27] writable limits Jiri Slaby
@ 2009-11-28 7:28 ` Ingo Molnar
0 siblings, 0 replies; 34+ messages in thread
From: Ingo Molnar @ 2009-11-28 7:28 UTC (permalink / raw)
To: Jiri Slaby
Cc: Jiri Slaby, nhorman, sfr, linux-kernel, akpm, marcin.slusarz,
tglx, mingo, hpa, torvalds, oleg, Stephen Smalley, Eric Paris,
David Howells
* Jiri Slaby <jirislaby@gmail.com> wrote:
> Hi,
>
> I broke the threading to not mess up with the long thread.
>
> In this version I got rid of the rlim access_only ugliness.
Thanks Jiri - this series looks very clean already and the helpers make
the various usage sites easier to understand as well.
One (very small) naming suggestion, please rename:
rlim_get_cur()
rlim_get_max()
task_rlim_get_cur()
task_rlim_get_max()
To a more natural sounding scheme like:
rlimit()
rlimit_max()
task_rlimit()
task_rlimit_max()
Reasons:
- 'cur' is a misnomer that came a decade+ ago from an ABI and there's
no need to continue that bad tradition in helper functions. It can
also be confused with 'curr' which we often use for the current task.
- 'rlimit' is general meme, plus there's no need to say it out aloud
that we 'get' it - rlimit() is obvious enough.
Beyond solving these issues it makes it shorter and more logical as
well.
Thanks,
Ingo
^ permalink raw reply [flat|nested] 34+ messages in thread