From: Jiri Slaby <jslaby@suse.cz>
To: jirislaby@gmail.com
Cc: Oleg Nesterov <oleg@redhat.com>,
akpm@linux-foundation.org, adobriyan@gmail.com,
nhorman@tuxdriver.com, Stephen Smalley <sds@tycho.nsa.gov>,
James Morris <jmorris@namei.org>,
Eric Paris <eparis@parisplace.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH v4 09/12] rlimits: redo do_setrlimit to more generic do_prlimit
Date: Wed, 23 Jun 2010 23:52:10 +0200 [thread overview]
Message-ID: <1277329933-8139-9-git-send-email-jslaby@suse.cz> (raw)
In-Reply-To: <1277329933-8139-1-git-send-email-jslaby@suse.cz>
It now allows also reading of limits. I.e. all read and writes will
later use this function.
It takes two parameters, new and old limits which can be both NULL.
If new is non-NULL, the value in it is set to rlimits.
If old is non-NULL, current rlimits are stored there.
If both are non-NULL, old are stored prior to setting the new ones,
atomically.
(Similar to sigaction.)
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
include/linux/resource.h | 4 +-
kernel/sys.c | 71 ++++++++++++++++++++++++----------------------
2 files changed, 39 insertions(+), 36 deletions(-)
diff --git a/include/linux/resource.h b/include/linux/resource.h
index 037aa7e..88d36f9 100644
--- a/include/linux/resource.h
+++ b/include/linux/resource.h
@@ -80,8 +80,8 @@ struct rlimit64 {
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);
+int do_prlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim, struct rlimit *old_rlim);
#endif /* __KERNEL__ */
diff --git a/kernel/sys.c b/kernel/sys.c
index c762eeb..bc7d1be 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1273,18 +1273,21 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
#endif
/* make sure you are allowed to change @tsk limits before calling this */
-int do_setrlimit(struct task_struct *tsk, unsigned int resource,
- struct rlimit *new_rlim)
+int do_prlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim, struct rlimit *old_rlim)
{
- struct rlimit *old_rlim;
+ struct rlimit *rlim;
int retval = 0;
if (resource >= RLIM_NLIMITS)
return -EINVAL;
- if (new_rlim->rlim_cur > new_rlim->rlim_max)
- return -EINVAL;
- if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
- return -EPERM;
+ if (new_rlim) {
+ if (new_rlim->rlim_cur > new_rlim->rlim_max)
+ return -EINVAL;
+ 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);
@@ -1293,42 +1296,42 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
goto out;
}
- old_rlim = tsk->signal->rlim + resource;
+ rlim = tsk->signal->rlim + resource;
task_lock(tsk->group_leader);
- if (new_rlim->rlim_max > old_rlim->rlim_max &&
- !capable(CAP_SYS_RESOURCE))
- retval = -EPERM;
- if (!retval)
- retval = security_task_setrlimit(tsk->group_leader, resource,
- new_rlim);
-
- if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
- /*
- * 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;
+ if (new_rlim) {
+ if (new_rlim->rlim_max > rlim->rlim_max &&
+ !capable(CAP_SYS_RESOURCE))
+ retval = -EPERM;
+ if (!retval)
+ retval = security_task_setrlimit(tsk->group_leader,
+ resource, new_rlim);
+ if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
+ /*
+ * 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;
+ }
+ }
+ if (!retval) {
+ if (old_rlim)
+ *old_rlim = *rlim;
+ if (new_rlim)
+ *rlim = *new_rlim;
}
-
- if (!retval)
- *old_rlim = *new_rlim;
task_unlock(tsk->group_leader);
- if (retval || resource != RLIMIT_CPU)
- goto out;
-
/*
* RLIMIT_CPU handling. Note that the kernel fails to return an error
* code if it rejected the user's attempt to set RLIMIT_CPU. This is a
* very long-standing error, and fixing it now risks breakage of
* applications, so we live with it
*/
- if (new_rlim->rlim_cur == RLIM_INFINITY)
- goto out;
-
- update_rlimit_cpu(tsk, new_rlim->rlim_cur);
+ if (!retval && new_rlim && resource == RLIMIT_CPU &&
+ new_rlim->rlim_cur != RLIM_INFINITY)
+ update_rlimit_cpu(tsk, new_rlim->rlim_cur);
out:
read_unlock(&tasklist_lock);
return retval;
@@ -1340,7 +1343,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
return -EFAULT;
- return do_setrlimit(current, resource, &new_rlim);
+ return do_prlimit(current, resource, &new_rlim, NULL);
}
/*
--
1.7.1
next prev parent reply other threads:[~2010-06-23 21:54 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-23 21:52 [PATCH v4 01/12] rlimits: security, add task_struct to setrlimit Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 02/12] rlimits: add task_struct to update_rlimit_cpu Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 03/12] rlimits: make sure ->rlim_max never grows in sys_setrlimit Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 04/12] rlimits: selinux, do rlimits changes under task_lock Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 05/12] rlimits: split sys_setrlimit Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 06/12] rlimits: allow setrlimit to non-current tasks Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 07/12] rlimits: do security check under task_lock Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 08/12] rlimits: add rlimit64 structure Jiri Slaby
2010-06-23 21:52 ` Jiri Slaby [this message]
2010-06-23 21:52 ` [PATCH v4 10/12] rlimits: switch more rlimit syscalls to do_prlimit Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 11/12] rlimits: implement prlimit64 syscall Jiri Slaby
2010-06-23 21:52 ` [PATCH v4 12/12] unistd: add __NR_prlimit64 syscall numbers Jiri Slaby
2010-06-23 23:58 ` [PATCH v4 01/12] rlimits: security, add task_struct to setrlimit James Morris
2010-07-02 11:30 ` Jiri Slaby
2010-07-05 0:32 ` James Morris
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1277329933-8139-9-git-send-email-jslaby@suse.cz \
--to=jslaby@suse.cz \
--cc=adobriyan@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=eparis@parisplace.org \
--cc=jirislaby@gmail.com \
--cc=jmorris@namei.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nhorman@tuxdriver.com \
--cc=oleg@redhat.com \
--cc=sds@tycho.nsa.gov \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®