summaryrefslogtreecommitdiff
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 571bba8c8989..a95e3900dc1e 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -24,6 +24,11 @@
#include <linux/dcookies.h>
#include <linux/suspend.h>
+/* Don't include this - it breaks ia64's cond_syscall() implementation */
+#if 0
+#include <linux/syscalls.h>
+#endif
+
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/unistd.h>
@@ -649,7 +654,7 @@ static int set_user(uid_t new_ruid, int dumpclear)
return -EAGAIN;
if (atomic_read(&new_user->processes) >=
- current->rlim[RLIMIT_NPROC].rlim_cur &&
+ current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
new_user != &root_user) {
free_uid(new_user);
return -EAGAIN;
@@ -1496,9 +1501,13 @@ asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim)
{
if (resource >= RLIM_NLIMITS)
return -EINVAL;
- else
- return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim))
- ? -EFAULT : 0;
+ else {
+ struct rlimit value;
+ task_lock(current->group_leader);
+ value = current->signal->rlim[resource];
+ task_unlock(current->group_leader);
+ return copy_to_user(rlim, &value, sizeof(*rlim)) ? -EFAULT : 0;
+ }
}
#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
@@ -1513,7 +1522,9 @@ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *r
if (resource >= RLIM_NLIMITS)
return -EINVAL;
- memcpy(&x, current->rlim + resource, sizeof(*rlim));
+ task_lock(current->group_leader);
+ x = current->signal->rlim[resource];
+ task_unlock(current->group_leader);
if(x.rlim_cur > 0x7FFFFFFF)
x.rlim_cur = 0x7FFFFFFF;
if(x.rlim_max > 0x7FFFFFFF)
@@ -1534,21 +1545,20 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
return -EFAULT;
if (new_rlim.rlim_cur > new_rlim.rlim_max)
return -EINVAL;
- old_rlim = current->rlim + resource;
- if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
- (new_rlim.rlim_max > old_rlim->rlim_max)) &&
+ 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) {
- if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
+ if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
return -EPERM;
- }
retval = security_task_setrlimit(resource, &new_rlim);
if (retval)
return retval;
+ task_lock(current->group_leader);
*old_rlim = new_rlim;
+ task_unlock(current->group_leader);
return 0;
}