[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#280800: gringotts: does not start on kernels >= 2.6.9



On Wed, Nov 17, 2004 at 11:43:43PM +0100, Bastian Kleineidam wrote:
> Hi,
> 
> I investigated a little more, and it seems[1] that usage of mlockall()
> under 2.6.9 kernels breaks some other functions, amongst them the
> needed getpwuid_r().
> [1] http://bugs.gentoo.org/show_bug.cgi?id=69458
> 
> Here are some configurations:
> 
> - gringotts binary is setuid, kernel 2.6.8 --> works
> - gringotts binary is setuid, kernel 2.6.9 --> broken
> - gringotts binary is setuid, kernel 2.6.9, being run with strace
>   or gdb --> works
> - gringotts binary is not setuid, kernel 2.6.[89] --> works
>   note: removing the setuid bit from gringotts disables the call
>   to mlockall()
> 
> I am CC'ing the kernel team; I have no idea why mlockall() is all
> of a sudden causing problems in 2.6.9 kernels.
> 
> If there is no immediate fix for this, I will upload a version
> with the setuid bit removed from /usr/bin/gringotts. Then the
> mlockall() feature will not be available.

Firstly, please note that 2.6.8 and not 2.6.9 is the target kernel for sarge.

The problem you are seeing would appear to be resolved by the attached
patch which I sucked down from upstream. Are you in a position to test
it? I can provide kernel-image packages (386) if it helps.

Reference: http://linux.bkbits.net:8080/linux-2.5/related/mm/mlock.c?nav=index.html|src/|src/mm

-- 
Horms
# origin: roland (BitKeeper)
# cset: 1.1988.75.29 (2.6) key=4174abc5dq-wXOEJcxf9Kzcs8_naPg
# inclusion: upstream
# descrition: [PATCH] make rlimit settings per-process instead of per-thread
# revision date: Mon, 22 Nov 2004 13:08:43 +0900
#
# S rset: ChangeSet|1.1988.75.28..1.1988.75.29
# I rset: fs/binfmt_flat.c|1.10..1.11
# I rset: arch/s390/mm/mmap.c|1.1..1.2
# I rset: include/linux/mm.h|1.191..1.192
# I rset: fs/open.c|1.68..1.69
# S rset: mm/mlock.c|1.13..1.14
# I rset: include/linux/init_task.h|1.31..1.32
# I rset: include/linux/sched.h|1.256..1.257
# I rset: kernel/fork.c|1.210..1.211
# I rset: kernel/sys.c|1.94..1.94.1.1
# I rset: arch/ppc64/mm/mmap.c|1.1..1.2
# I rset: fs/binfmt_aout.c|1.24..1.25
# I rset: arch/sparc64/solaris/fs.c|1.20..1.21
# I rset: fs/exec.c|1.134..1.135
# I rset: kernel/signal.c|1.134..1.135
# I rset: arch/sparc/kernel/sys_sunos.c|1.33..1.34
# I rset: arch/ia64/mm/init.c|1.69..1.70
# I rset: fs/binfmt_elf.c|1.88..1.89
# I rset: arch/i386/mm/mmap.c|1.2..1.3
# S rset: mm/memory.c|1.189..1.190
# I rset: arch/sparc64/kernel/binfmt_aout32.c|1.12..1.13
# I rset: ipc/mqueue.c|1.17..1.18
# I rset: kernel/acct.c|1.35..1.36
# I rset: mm/mremap.c|1.57..1.58
# I rset: fs/nfsd/nfssvc.c|1.42..1.43
# I rset: arch/ia64/kernel/sys_ia64.c|1.31..1.32
# I rset: fs/buffer.c|1.257..1.258
# I rset: fs/proc/array.c|1.69..1.70
# I rset: arch/sparc64/kernel/sys_sunos32.c|1.45..1.46
# I rset: mm/mmap.c|1.146..1.147
# I rset: fs/fcntl.c|1.40..1.41
# I rset: include/linux/security.h|1.38..1.39
# I rset: kernel/timer.c|1.95..1.96
# I rset: mm/nommu.c|1.16..1.17
# I rset: kernel/exit.c|1.156..1.157
# I rset: fs/nfs/direct.c|1.18..1.19
# I rset: arch/mips/kernel/sysirix.c|1.27..1.28
# I rset: arch/ia64/kernel/perfmon.c|1.94..1.95
# I rset: security/selinux/hooks.c|1.63..1.64
# I rset: arch/ia64/mm/fault.c|1.21..1.22
# I rset: arch/x86_64/ia32/ia32_aout.c|1.4..1.5
# I rset: arch/mips/kernel/irixelf.c|1.11..1.12
# I rset: mm/filemap.c|1.274..1.275
#
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/10/18 22:53:09-07:00 roland@redhat.com 
#   [PATCH] make rlimit settings per-process instead of per-thread
#   
#   POSIX specifies that the limit settings provided by getrlimit/setrlimit are
#   shared by the whole process, not specific to individual threads.  This
#   patch changes the behavior of those calls to comply with POSIX.
#   
#   I've moved the struct rlimit array from task_struct to signal_struct, as it
#   has the correct sharing properties.  (This reduces kernel memory usage per
#   thread in multithreaded processes by around 100/200 bytes for 32/64
#   machines respectively.)  I took a fairly minimal approach to the locking
#   issues with the newly shared struct rlimit array.  It turns out that all
#   the code that is checking limits really just needs to look at one word at a
#   time (one rlim_cur field, usually).  It's only the few places like
#   getrlimit itself (and fork), that require atomicity in accessing a whole
#   struct rlimit, so I just used a spin lock for them and no locking for most
#   of the checks.  If it turns out that readers of struct rlimit need more
#   atomicity where they are now cheap, or less overhead where they are now
#   atomic (e.g. fork), then seqcount is certainly the right thing to use for
#   them instead of readers using the spin lock.  Though it's in signal_struct,
#   I didn't use siglock since the access to rlimits never needs to disable
#   irqs and doesn't overlap with other siglock uses.  Instead of adding
#   something new, I overloaded task_lock(task->group_leader) for this; it is
#   used for other things that are not likely to happen simultaneously with
#   limit tweaking.  To me that seems preferable to adding a word, but it would
#   be trivial (and arguably cleaner) to add a separate lock for these users
#   (or e.g. just use seqlock, which adds two words but is optimal for readers).
#   
#   Most of the changes here are just the trivial s/->rlim/->signal->rlim/. 
#   
#   I stumbled across what must be a long-standing bug, in reparent_to_init.
#   It does:
#   	memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim)));
#   when surely it was intended to be:
#   	memcpy(current->rlim, init_task.rlim, sizeof(current->rlim));
#   As rlim is an array, the * in the sizeof expression gets the size of the
#   first element, so this just changes the first limit (RLIMIT_CPU).  This is
#   for kernel threads, where it's clear that resetting all the rlimits is what
#   you want.  With that fixed, the setting of RLIMIT_FSIZE in nfsd is
#   superfluous since it will now already have been reset to RLIM_INFINITY.
#   
#   The other subtlety is removing:
#   	tsk->rlim[RLIMIT_CPU].rlim_cur = RLIM_INFINITY;
#   in exit_notify, which was to avoid a race signalling during self-reaping
#   exit.  As the limit is now shared, a dying thread should not change it for
#   others.  Instead, I avoid that race by checking current->state before the
#   RLIMIT_CPU check.  (Adding one new conditional in that path is now required
#   one way or another, since if not for this check there would also be a new
#   race with self-reaping exit later on clearing current->signal that would
#   have to be checked for.)
#   
#   The one loose end left by this patch is with process accounting.
#   do_acct_process temporarily resets the RLIMIT_FSIZE limit while writing the
#   accounting record.  I left this as it was, but it is now changing a limit
#   that might be shared by other threads still running.  I left this in a
#   dubious state because it seems to me that processing accounting may already
#   be more generally a dubious state when it comes to NPTL threads.  I would
#   think you would want one record per process, with aggregate data about all
#   threads that ever lived in it, not a separate record for each thread.
#   I don't use process accounting myself, but if anyone is interested in
#   testing it out I could provide a patch to change it this way.
#   
#   One final note, this is not 100% to POSIX compliance in regards to rlimits.
#   POSIX specifies that RLIMIT_CPU refers to a whole process in aggregate, not
#   to each individual thread.  I will provide patches later on to achieve that
#   change, assuming this patch goes in first.
#   
#   Signed-off-by: Roland McGrath <roland@redhat.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# security/selinux/hooks.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +3 -3
#   make rlimit settings per-process instead of per-thread
# 
# mm/nommu.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# mm/mremap.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +2 -2
#   make rlimit settings per-process instead of per-thread
# 
# mm/mmap.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +9 -9
#   make rlimit settings per-process instead of per-thread
# 
# mm/mlock.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +3 -3
#   make rlimit settings per-process instead of per-thread
# 
# mm/memory.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# mm/filemap.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# kernel/timer.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +3 -2
#   make rlimit settings per-process instead of per-thread
# 
# kernel/sys.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +16 -11
#   make rlimit settings per-process instead of per-thread
# 
# kernel/signal.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +2 -2
#   make rlimit settings per-process instead of per-thread
# 
# kernel/fork.c
#   2004/10/18 22:28:18-07:00 roland@redhat.com +7 -3
#   make rlimit settings per-process instead of per-thread
# 
# kernel/exit.c
#   2004/10/18 22:28:20-07:00 roland@redhat.com +2 -2
#   make rlimit settings per-process instead of per-thread
# 
# kernel/acct.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +3 -3
#   make rlimit settings per-process instead of per-thread
# 
# ipc/mqueue.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# include/linux/security.h
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# include/linux/sched.h
#   2004/10/18 22:28:06-07:00 roland@redhat.com +11 -2
#   make rlimit settings per-process instead of per-thread
# 
# include/linux/mm.h
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# include/linux/init_task.h
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# fs/proc/array.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +3 -1
#   make rlimit settings per-process instead of per-thread
# 
# fs/open.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# fs/nfsd/nfssvc.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +0 -1
#   make rlimit settings per-process instead of per-thread
# 
# fs/nfs/direct.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# fs/fcntl.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +3 -3
#   make rlimit settings per-process instead of per-thread
# 
# fs/exec.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +2 -2
#   make rlimit settings per-process instead of per-thread
# 
# fs/buffer.c
#   2004/10/18 22:28:19-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# fs/binfmt_flat.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# fs/binfmt_elf.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# fs/binfmt_aout.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +5 -5
#   make rlimit settings per-process instead of per-thread
# 
# arch/x86_64/ia32/ia32_aout.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +3 -3
#   make rlimit settings per-process instead of per-thread
# 
# arch/sparc64/solaris/fs.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +8 -8
#   make rlimit settings per-process instead of per-thread
# 
# arch/sparc64/kernel/sys_sunos32.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# arch/sparc64/kernel/binfmt_aout32.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +3 -3
#   make rlimit settings per-process instead of per-thread
# 
# arch/sparc/kernel/sys_sunos.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# arch/s390/mm/mmap.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +2 -2
#   make rlimit settings per-process instead of per-thread
# 
# arch/ppc64/mm/mmap.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +2 -2
#   make rlimit settings per-process instead of per-thread
# 
# arch/mips/kernel/sysirix.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +12 -7
#   make rlimit settings per-process instead of per-thread
# 
# arch/mips/kernel/irixelf.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# arch/ia64/mm/init.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# arch/ia64/mm/fault.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +2 -2
#   make rlimit settings per-process instead of per-thread
# 
# arch/ia64/kernel/sys_ia64.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +1 -1
#   make rlimit settings per-process instead of per-thread
# 
# arch/ia64/kernel/perfmon.c
#   2004/10/18 22:28:03-07:00 roland@redhat.com +2 -1
#   make rlimit settings per-process instead of per-thread
# 
# arch/i386/mm/mmap.c
#   2004/10/18 22:26:36-07:00 roland@redhat.com +2 -2
#   make rlimit settings per-process instead of per-thread
# 
#
===== fs/binfmt_flat.c 1.10 vs 1.11 =====
--- 1.10/fs/binfmt_flat.c	2004-06-18 15:41:09 +09:00
+++ 1.11/fs/binfmt_flat.c	2004-10-19 14:26:36 +09:00
@@ -486,7 +486,7 @@
 	 * size limits imposed on them by creating programs with large
 	 * arrays in the data or bss.
 	 */
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (data_len + bss_len > rlim)
===== arch/s390/mm/mmap.c 1.1 vs 1.2 =====
--- 1.1/arch/s390/mm/mmap.c	2004-08-24 18:08:16 +09:00
+++ 1.2/arch/s390/mm/mmap.c	2004-10-19 14:26:36 +09:00
@@ -37,7 +37,7 @@
 
 static inline unsigned long mmap_base(void)
 {
-	unsigned long gap = current->rlim[RLIMIT_STACK].rlim_cur;
+	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
 
 	if (gap < MIN_GAP)
 		gap = MIN_GAP;
@@ -58,7 +58,7 @@
 #endif
 	return sysctl_legacy_va_layout ||
 	    (current->personality & ADDR_COMPAT_LAYOUT) ||
-	    current->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY;
+	    current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY;
 }
 
 /*
===== include/linux/mm.h 1.191 vs 1.192 =====
--- 1.191/include/linux/mm.h	2004-09-03 18:08:15 +09:00
+++ 1.192/include/linux/mm.h	2004-10-19 14:26:36 +09:00
@@ -540,7 +540,7 @@
 {
 	if (capable(CAP_IPC_LOCK))
 		return 1;
-	if (current->rlim[RLIMIT_MEMLOCK].rlim_cur != 0)
+	if (current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur != 0)
 		return 1;
 	return 0;
 }
===== fs/open.c 1.68 vs 1.69 =====
--- 1.68/fs/open.c	2004-08-08 10:54:13 +09:00
+++ 1.69/fs/open.c	2004-10-19 14:28:19 +09:00
@@ -852,7 +852,7 @@
 	 * N.B. For clone tasks sharing a files structure, this test
 	 * will limit the total number of files that can be opened.
 	 */
-	if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+	if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
 		goto out;
 
 	/* Do we need to expand the fdset array? */
===== include/linux/init_task.h 1.31 vs 1.32 =====
--- 1.31/include/linux/init_task.h	2004-06-30 14:39:28 +09:00
+++ 1.32/include/linux/init_task.h	2004-10-19 14:26:36 +09:00
@@ -50,6 +50,7 @@
 		.list = LIST_HEAD_INIT(sig.shared_pending.list),	\
 		.signal =  {{0}}}, \
 	.posix_timers	 = LIST_HEAD_INIT(sig.posix_timers),		\
+	.rlim		= INIT_RLIMITS,					\
 }
 
 #define INIT_SIGHAND(sighand) {	\
@@ -96,7 +97,6 @@
 	.cap_inheritable = CAP_INIT_INH_SET,				\
 	.cap_permitted	= CAP_FULL_SET,					\
 	.keep_capabilities = 0,						\
-	.rlim		= INIT_RLIMITS,					\
 	.user		= INIT_USER,					\
 	.comm		= "swapper",					\
 	.thread		= INIT_THREAD,					\
===== include/linux/sched.h 1.256 vs 1.257 =====
--- 1.256/include/linux/sched.h	2004-10-14 13:08:29 +09:00
+++ 1.257/include/linux/sched.h	2004-10-19 14:28:06 +09:00
@@ -312,6 +312,17 @@
 	unsigned long utime, stime, cutime, cstime;
 	unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
 	unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
+
+	/*
+	 * We don't bother to synchronize most readers of this at all,
+	 * because there is no reader checking a limit that actually needs
+	 * to get both rlim_cur and rlim_max atomically, and either one
+	 * alone is a single word that can safely be read normally.
+	 * getrlimit/setrlimit use task_lock(current->group_leader) to
+	 * protect this instead of the siglock, because they really
+	 * have no need to disable irqs.
+	 */
+	struct rlimit rlim[RLIM_NLIMITS];
 };
 
 /*
@@ -518,8 +529,6 @@
 	kernel_cap_t   cap_effective, cap_inheritable, cap_permitted;
 	unsigned keep_capabilities:1;
 	struct user_struct *user;
-/* limits */
-	struct rlimit rlim[RLIM_NLIMITS];
 	unsigned short used_math;
 	char comm[16];
 /* file system info */
===== kernel/fork.c 1.210 vs 1.211 =====
--- 1.210/kernel/fork.c	2004-10-14 13:08:29 +09:00
+++ 1.211/kernel/fork.c	2004-10-19 14:28:18 +09:00
@@ -249,8 +249,8 @@
 	if(max_threads < 20)
 		max_threads = 20;
 
-	init_task.rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
-	init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
+	init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
+	init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
 }
 
 static struct task_struct *dup_task_struct(struct task_struct *orig)
@@ -872,6 +872,10 @@
 	sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
 	sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
 
+	task_lock(current->group_leader);
+	memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
+	task_unlock(current->group_leader);
+
 	return 0;
 }
 
@@ -941,7 +945,7 @@
 
 	retval = -EAGAIN;
 	if (atomic_read(&p->user->processes) >=
-			p->rlim[RLIMIT_NPROC].rlim_cur) {
+			p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
 		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
 				p->user != &root_user)
 			goto bad_fork_free;
===== kernel/sys.c 1.94 vs 1.94.1.1 =====
--- 1.94/kernel/sys.c	2004-09-28 08:37:09 +09:00
+++ 1.94.1.1/kernel/sys.c	2004-10-19 14:28:19 +09:00
@@ -649,7 +649,7 @@
 		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 +1496,13 @@
 {
 	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 +1517,9 @@
 	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 +1540,20 @@
 		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;
 }
 
===== arch/ppc64/mm/mmap.c 1.1 vs 1.2 =====
--- 1.1/arch/ppc64/mm/mmap.c	2004-08-24 18:08:17 +09:00
+++ 1.2/arch/ppc64/mm/mmap.c	2004-10-19 14:26:36 +09:00
@@ -37,7 +37,7 @@
 
 static inline unsigned long mmap_base(void)
 {
-	unsigned long gap = current->rlim[RLIMIT_STACK].rlim_cur;
+	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
 
 	if (gap < MIN_GAP)
 		gap = MIN_GAP;
@@ -58,7 +58,7 @@
 	if (current->personality & ADDR_COMPAT_LAYOUT)
 		return 1;
 
-	if (current->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
 		return 1;
 
 	return sysctl_legacy_va_layout;
===== fs/binfmt_aout.c 1.24 vs 1.25 =====
--- 1.24/fs/binfmt_aout.c	2004-08-24 18:08:15 +09:00
+++ 1.25/fs/binfmt_aout.c	2004-10-19 14:26:36 +09:00
@@ -118,22 +118,22 @@
    if we wrote the stack, but not the data area.  */
 #ifdef __sparc__
 	if ((dump.u_dsize+dump.u_ssize) >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
+	    current->signal->rlim[RLIMIT_CORE].rlim_cur)
 		dump.u_dsize = 0;
 #else
 	if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
+	    current->signal->rlim[RLIMIT_CORE].rlim_cur)
 		dump.u_dsize = 0;
 #endif
 
 /* Make sure we have enough room to write the stack and data areas. */
 #ifdef __sparc__
 	if ((dump.u_ssize) >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
+	    current->signal->rlim[RLIMIT_CORE].rlim_cur)
 		dump.u_ssize = 0;
 #else
 	if ((dump.u_ssize+1) * PAGE_SIZE >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
+	    current->signal->rlim[RLIMIT_CORE].rlim_cur)
 		dump.u_ssize = 0;
 #endif
 
@@ -278,7 +278,7 @@
 	 * size limits imposed on them by creating programs with large
 	 * arrays in the data or bss.
 	 */
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (ex.a_data + ex.a_bss > rlim)
===== arch/sparc64/solaris/fs.c 1.20 vs 1.21 =====
--- 1.20/arch/sparc64/solaris/fs.c	2004-07-27 03:36:33 +09:00
+++ 1.21/arch/sparc64/solaris/fs.c	2004-10-19 14:26:36 +09:00
@@ -600,23 +600,23 @@
 {
 	switch (cmd) {
 	case 1: /* UL_GETFSIZE - in 512B chunks */
-		return current->rlim[RLIMIT_FSIZE].rlim_cur >> 9;
+		return current->signal->rlim[RLIMIT_FSIZE].rlim_cur >> 9;
 	case 2: /* UL_SETFSIZE */
 		if ((unsigned long)val > (LONG_MAX>>9)) return -ERANGE;
 		val <<= 9;
-		lock_kernel();
-		if (val > current->rlim[RLIMIT_FSIZE].rlim_max) {
+		task_lock(current->group_leader);
+		if (val > current->signal->rlim[RLIMIT_FSIZE].rlim_max) {
 			if (!capable(CAP_SYS_RESOURCE)) {
-				unlock_kernel();
+				task_unlock(current->group_leader);
 				return -EPERM;
 			}
-			current->rlim[RLIMIT_FSIZE].rlim_max = val;
+			current->signal->rlim[RLIMIT_FSIZE].rlim_max = val;
 		}
-		current->rlim[RLIMIT_FSIZE].rlim_cur = val;
-		unlock_kernel();
+		current->signal->rlim[RLIMIT_FSIZE].rlim_cur = val;
+		task_unlock(current->group_leader);
 		return 0;
 	case 3: /* UL_GMEMLIM */
-		return current->rlim[RLIMIT_DATA].rlim_cur;
+		return current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	case 4: /* UL_GDESLIM */
 		return NR_OPEN;
 	}
===== fs/exec.c 1.134 vs 1.135 =====
--- 1.134/fs/exec.c	2004-09-17 15:58:37 +09:00
+++ 1.135/fs/exec.c	2004-10-19 14:28:19 +09:00
@@ -377,7 +377,7 @@
 	bprm->p = PAGE_SIZE * i - offset;
 
 	/* Limit stack size to 1GB */
-	stack_base = current->rlim[RLIMIT_STACK].rlim_max;
+	stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max;
 	if (stack_base > (1 << 30))
 		stack_base = 1 << 30;
 	stack_base = PAGE_ALIGN(STACK_TOP - stack_base);
@@ -1393,7 +1393,7 @@
 	current->signal->group_exit_code = exit_code;
 	coredump_wait(mm);
 
-	if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
+	if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
 		goto fail_unlock;
 
 	/*
===== kernel/signal.c 1.134 vs 1.135 =====
--- 1.134/kernel/signal.c	2004-09-15 17:26:18 +09:00
+++ 1.135/kernel/signal.c	2004-10-19 14:28:19 +09:00
@@ -269,7 +269,7 @@
 	struct sigqueue *q = NULL;
 
 	if (atomic_read(&current->user->sigpending) <
-			current->rlim[RLIMIT_SIGPENDING].rlim_cur)
+			current->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
 		q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
 	if (q) {
 		INIT_LIST_HEAD(&q->list);
@@ -764,7 +764,7 @@
 	   pass on the info struct.  */
 
 	if (atomic_read(&t->user->sigpending) <
-			t->rlim[RLIMIT_SIGPENDING].rlim_cur)
+			t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
 		q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
 
 	if (q) {
===== arch/sparc/kernel/sys_sunos.c 1.33 vs 1.34 =====
--- 1.33/arch/sparc/kernel/sys_sunos.c	2004-07-13 22:07:16 +09:00
+++ 1.34/arch/sparc/kernel/sys_sunos.c	2004-10-19 14:26:36 +09:00
@@ -178,7 +178,7 @@
 	 * Check against rlimit and stack..
 	 */
 	retval = -ENOMEM;
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (brk - current->mm->end_code > rlim)
===== arch/ia64/mm/init.c 1.69 vs 1.70 =====
--- 1.69/arch/ia64/mm/init.c	2004-10-06 03:27:40 +09:00
+++ 1.70/arch/ia64/mm/init.c	2004-10-19 14:26:36 +09:00
@@ -98,7 +98,7 @@
 inline void
 ia64_set_rbs_bot (void)
 {
-	unsigned long stack_size = current->rlim[RLIMIT_STACK].rlim_max & -16;
+	unsigned long stack_size = current->signal->rlim[RLIMIT_STACK].rlim_max & -16;
 
 	if (stack_size > MAX_USER_STACK_SIZE)
 		stack_size = MAX_USER_STACK_SIZE;
===== fs/binfmt_elf.c 1.88 vs 1.89 =====
--- 1.88/fs/binfmt_elf.c	2004-09-23 05:34:05 +09:00
+++ 1.89/fs/binfmt_elf.c	2004-10-19 14:26:36 +09:00
@@ -1314,7 +1314,7 @@
 	struct vm_area_struct *vma;
 	struct elfhdr *elf = NULL;
 	off_t offset = 0, dataoff;
-	unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur;
+	unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
 	int numnote;
 	struct memelfnote *notes = NULL;
 	struct elf_prstatus *prstatus = NULL;	/* NT_PRSTATUS */
===== arch/i386/mm/mmap.c 1.2 vs 1.3 =====
--- 1.2/arch/i386/mm/mmap.c	2004-08-24 18:08:15 +09:00
+++ 1.3/arch/i386/mm/mmap.c	2004-10-19 14:26:36 +09:00
@@ -37,7 +37,7 @@
 
 static inline unsigned long mmap_base(struct mm_struct *mm)
 {
-	unsigned long gap = current->rlim[RLIMIT_STACK].rlim_cur;
+	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
 
 	if (gap < MIN_GAP)
 		gap = MIN_GAP;
@@ -59,7 +59,7 @@
 	 */
 	if (sysctl_legacy_va_layout ||
 			(current->personality & ADDR_COMPAT_LAYOUT) ||
-			current->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
+			current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
 		mm->mmap_base = TASK_UNMAPPED_BASE;
 		mm->get_unmapped_area = arch_get_unmapped_area;
 		mm->unmap_area = arch_unmap_area;
===== arch/sparc64/kernel/binfmt_aout32.c 1.12 vs 1.13 =====
--- 1.12/arch/sparc64/kernel/binfmt_aout32.c	2004-07-27 03:37:42 +09:00
+++ 1.13/arch/sparc64/kernel/binfmt_aout32.c	2004-10-19 14:26:36 +09:00
@@ -102,12 +102,12 @@
 /* If the size of the dump file exceeds the rlimit, then see what would happen
    if we wrote the stack, but not the data area.  */
 	if ((dump.u_dsize+dump.u_ssize) >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
+	    current->signal->rlim[RLIMIT_CORE].rlim_cur)
 		dump.u_dsize = 0;
 
 /* Make sure we have enough room to write the stack and data areas. */
 	if ((dump.u_ssize) >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
+	    current->signal->rlim[RLIMIT_CORE].rlim_cur)
 		dump.u_ssize = 0;
 
 /* make sure we actually have a data and stack area to dump */
@@ -218,7 +218,7 @@
 	 * size limits imposed on them by creating programs with large
 	 * arrays in the data or bss.
 	 */
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (ex.a_data + ex.a_bss > rlim)
===== ipc/mqueue.c 1.17 vs 1.18 =====
--- 1.17/ipc/mqueue.c	2004-08-23 17:15:23 +09:00
+++ 1.18/ipc/mqueue.c	2004-10-19 14:28:19 +09:00
@@ -145,7 +145,7 @@
 			spin_lock(&mq_lock);
 			if (u->mq_bytes + mq_bytes < u->mq_bytes ||
 		 	    u->mq_bytes + mq_bytes >
-			    p->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
+			    p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
 				spin_unlock(&mq_lock);
 				goto out_inode;
 			}
===== kernel/acct.c 1.35 vs 1.36 =====
--- 1.35/kernel/acct.c	2004-10-14 13:08:29 +09:00
+++ 1.36/kernel/acct.c	2004-10-19 14:28:19 +09:00
@@ -488,11 +488,11 @@
 	/*
  	 * Accounting records are not subject to resource limits.
  	 */
-	flim = current->rlim[RLIMIT_FSIZE].rlim_cur;
-	current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
+	flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+	current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 	file->f_op->write(file, (char *)&ac,
 			       sizeof(acct_t), &file->f_pos);
-	current->rlim[RLIMIT_FSIZE].rlim_cur = flim;
+	current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
 	set_fs(fs);
 }
 
===== mm/mremap.c 1.57 vs 1.58 =====
--- 1.57/mm/mremap.c	2004-08-27 16:02:34 +09:00
+++ 1.58/mm/mremap.c	2004-10-19 14:28:19 +09:00
@@ -327,7 +327,7 @@
 	if (vma->vm_flags & VM_LOCKED) {
 		unsigned long locked, lock_limit;
 		locked = current->mm->locked_vm << PAGE_SHIFT;
-		lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+		lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
 		locked += new_len - old_len;
 		ret = -EAGAIN;
 		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
@@ -335,7 +335,7 @@
 	}
 	ret = -ENOMEM;
 	if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
-	    > current->rlim[RLIMIT_AS].rlim_cur)
+	    > current->signal->rlim[RLIMIT_AS].rlim_cur)
 		goto out;
 
 	if (vma->vm_flags & VM_ACCOUNT) {
===== fs/nfsd/nfssvc.c 1.42 vs 1.43 =====
--- 1.42/fs/nfsd/nfssvc.c	2004-09-08 15:33:02 +09:00
+++ 1.43/fs/nfsd/nfssvc.c	2004-10-19 14:26:36 +09:00
@@ -180,7 +180,6 @@
 	/* Lock module and set up kernel thread */
 	lock_kernel();
 	daemonize("nfsd");
-	current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 
 	/* After daemonize() this kernel thread shares current->fs
 	 * with the init process. We need to create files with a
===== arch/ia64/kernel/sys_ia64.c 1.31 vs 1.32 =====
--- 1.31/arch/ia64/kernel/sys_ia64.c	2004-10-06 03:27:40 +09:00
+++ 1.32/arch/ia64/kernel/sys_ia64.c	2004-10-19 14:26:36 +09:00
@@ -138,7 +138,7 @@
 		goto out;
 
 	/* Check against rlimit.. */
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
 		goto out;
 
===== fs/buffer.c 1.257 vs 1.258 =====
--- 1.257/fs/buffer.c	2004-09-09 19:53:17 +09:00
+++ 1.258/fs/buffer.c	2004-10-19 14:28:19 +09:00
@@ -2232,7 +2232,7 @@
 	int err;
 
 	err = -EFBIG;
-        limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+        limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
 	if (limit != RLIM_INFINITY && size > (loff_t)limit) {
 		send_sig(SIGXFSZ, current, 0);
 		goto out;
===== fs/proc/array.c 1.69 vs 1.70 =====
--- 1.69/fs/proc/array.c	2004-10-14 13:08:29 +09:00
+++ 1.70/fs/proc/array.c	2004-10-19 14:28:19 +09:00
@@ -313,6 +313,7 @@
 	struct mm_struct *mm;
 	unsigned long long start_time;
 	unsigned long cmin_flt = 0, cmaj_flt = 0, cutime = 0, cstime = 0;
+	unsigned long rsslim = 0;
 	char tcomm[sizeof(task->comm)];
 
 	state = *get_task_state(task);
@@ -347,6 +348,7 @@
 		cmaj_flt = task->signal->cmaj_flt;
 		cutime = task->signal->cutime;
 		cstime = task->signal->cstime;
+		rsslim = task->signal->rlim[RLIMIT_RSS].rlim_cur;
 	}
 	read_unlock(&tasklist_lock);
 
@@ -393,7 +395,7 @@
 		start_time,
 		vsize,
 		mm ? mm->rss : 0, /* you might want to shift this left 3 */
-		task->rlim[RLIMIT_RSS].rlim_cur,
+	        rsslim,
 		mm ? mm->start_code : 0,
 		mm ? mm->end_code : 0,
 		mm ? mm->start_stack : 0,
===== arch/sparc64/kernel/sys_sunos32.c 1.45 vs 1.46 =====
--- 1.45/arch/sparc64/kernel/sys_sunos32.c	2004-07-13 21:57:19 +09:00
+++ 1.46/arch/sparc64/kernel/sys_sunos32.c	2004-10-19 14:26:36 +09:00
@@ -142,7 +142,7 @@
 	}
 	/* Check against rlimit and stack.. */
 	retval = -ENOMEM;
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (brk - current->mm->end_code > rlim)
===== mm/mmap.c 1.146 vs 1.147 =====
--- 1.146/mm/mmap.c	2004-10-04 08:03:11 +09:00
+++ 1.147/mm/mmap.c	2004-10-19 14:26:36 +09:00
@@ -136,7 +136,7 @@
 	}
 
 	/* Check against rlimit.. */
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
 		goto out;
 
@@ -833,7 +833,7 @@
 	if (vm_flags & VM_LOCKED) {
 		unsigned long locked, lock_limit;
 		locked = mm->locked_vm << PAGE_SHIFT;
-		lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+		lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
 		locked += len;
 		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
 			return -EAGAIN;
@@ -905,7 +905,7 @@
 
 	/* Check against address space limit. */
 	if ((mm->total_vm << PAGE_SHIFT) + len
-	    > current->rlim[RLIMIT_AS].rlim_cur)
+	    > current->signal->rlim[RLIMIT_AS].rlim_cur)
 		return -ENOMEM;
 
 	if (accountable && (!(flags & MAP_NORESERVE) ||
@@ -1350,9 +1350,9 @@
 		return -ENOMEM;
 	}
 	
-	if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
+	if (address - vma->vm_start > current->signal->rlim[RLIMIT_STACK].rlim_cur ||
 			((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
-			current->rlim[RLIMIT_AS].rlim_cur) {
+			current->signal->rlim[RLIMIT_AS].rlim_cur) {
 		anon_vma_unlock(vma);
 		vm_unacct_memory(grow);
 		return -ENOMEM;
@@ -1412,9 +1412,9 @@
 		return -ENOMEM;
 	}
 	
-	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
+	if (vma->vm_end - address > current->signal->rlim[RLIMIT_STACK].rlim_cur ||
 			((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
-			current->rlim[RLIMIT_AS].rlim_cur) {
+			current->signal->rlim[RLIMIT_AS].rlim_cur) {
 		anon_vma_unlock(vma);
 		vm_unacct_memory(grow);
 		return -ENOMEM;
@@ -1760,7 +1760,7 @@
 	if (mm->def_flags & VM_LOCKED) {
 		unsigned long locked, lock_limit;
 		locked = mm->locked_vm << PAGE_SHIFT;
-		lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+		lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
 		locked += len;
 		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
 			return -EAGAIN;
@@ -1779,7 +1779,7 @@
 
 	/* Check against address space limits *after* clearing old maps... */
 	if ((mm->total_vm << PAGE_SHIFT) + len
-	    > current->rlim[RLIMIT_AS].rlim_cur)
+	    > current->signal->rlim[RLIMIT_AS].rlim_cur)
 		return -ENOMEM;
 
 	if (mm->map_count > sysctl_max_map_count)
===== fs/fcntl.c 1.40 vs 1.41 =====
--- 1.40/fs/fcntl.c	2004-09-02 18:48:03 +09:00
+++ 1.41/fs/fcntl.c	2004-10-19 14:28:19 +09:00
@@ -86,7 +86,7 @@
 	int error;
 
 	error = -EINVAL;
-	if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+	if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
 		goto out;
 
 repeat:
@@ -105,7 +105,7 @@
 	}
 	
 	error = -EMFILE;
-	if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+	if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
 		goto out;
 
 	error = expand_files(files, newfd);
@@ -161,7 +161,7 @@
 	if (newfd == oldfd)
 		goto out_unlock;
 	err = -EBADF;
-	if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+	if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
 		goto out_unlock;
 	get_file(file);			/* We are now finished with oldfd */
 
===== include/linux/security.h 1.38 vs 1.39 =====
--- 1.38/include/linux/security.h	2004-06-19 03:43:31 +09:00
+++ 1.39/include/linux/security.h	2004-10-19 14:26:36 +09:00
@@ -582,7 +582,7 @@
  * @task_setrlimit:
  *	Check permission before setting the resource limits of the current
  *	process for @resource to @new_rlim.  The old resource limit values can
- *	be examined by dereferencing (current->rlim + resource).
+ *	be examined by dereferencing (current->signal->rlim + resource).
  *	@resource contains the resource whose limit is being set.
  *	@new_rlim contains the new limits for @resource.
  *	Return 0 if permission is granted.
===== kernel/timer.c 1.95 vs 1.96 =====
--- 1.95/kernel/timer.c	2004-10-03 13:05:10 +09:00
+++ 1.96/kernel/timer.c	2004-10-19 14:28:19 +09:00
@@ -805,12 +805,13 @@
 
 	psecs = (p->utime += user);
 	psecs += (p->stime += system);
-	if (psecs / HZ >= p->rlim[RLIMIT_CPU].rlim_cur) {
+	if (!unlikely(p->state & (TASK_DEAD|TASK_ZOMBIE)) &&
+	    psecs / HZ >= p->signal->rlim[RLIMIT_CPU].rlim_cur) {
 		/* Send SIGXCPU every second.. */
 		if (!(psecs % HZ))
 			send_sig(SIGXCPU, p, 1);
 		/* and SIGKILL when we go over max.. */
-		if (psecs / HZ >= p->rlim[RLIMIT_CPU].rlim_max)
+		if (psecs / HZ >= p->signal->rlim[RLIMIT_CPU].rlim_max)
 			send_sig(SIGKILL, p, 1);
 	}
 }
===== mm/nommu.c 1.16 vs 1.17 =====
--- 1.16/mm/nommu.c	2004-09-30 22:34:51 +09:00
+++ 1.17/mm/nommu.c	2004-10-19 14:28:19 +09:00
@@ -57,7 +57,7 @@
 	goto out_truncate;
 
 do_expand:
-	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
 	if (limit != RLIM_INFINITY && offset > limit)
 		goto out_sig;
 	if (offset > inode->i_sb->s_maxbytes)
===== kernel/exit.c 1.156 vs 1.157 =====
--- 1.156/kernel/exit.c	2004-10-17 10:24:37 +09:00
+++ 1.157/kernel/exit.c	2004-10-19 14:28:20 +09:00
@@ -237,7 +237,8 @@
 	/* rt_priority? */
 	/* signals? */
 	security_task_reparent_to_init(current);
-	memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim)));
+	memcpy(current->signal->rlim, init_task.signal->rlim,
+	       sizeof(current->signal->rlim));
 	atomic_inc(&(INIT_USER->__count));
 	switch_uid(INIT_USER);
 
@@ -761,7 +762,6 @@
 	 */
 	tsk->it_virt_value = 0;
 	tsk->it_prof_value = 0;
-	tsk->rlim[RLIMIT_CPU].rlim_cur = RLIM_INFINITY;
 
 	write_unlock_irq(&tasklist_lock);
 
===== fs/nfs/direct.c 1.18 vs 1.19 =====
--- 1.18/fs/nfs/direct.c	2004-06-07 02:11:40 +09:00
+++ 1.19/fs/nfs/direct.c	2004-10-19 14:26:36 +09:00
@@ -545,7 +545,7 @@
 {
 	ssize_t retval = -EINVAL;
 	loff_t *ppos = &iocb->ki_pos;
-	unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
 	struct file *file = iocb->ki_filp;
 	struct nfs_open_context *ctx =
 			(struct nfs_open_context *) file->private_data;
===== arch/mips/kernel/sysirix.c 1.27 vs 1.28 =====
--- 1.27/arch/mips/kernel/sysirix.c	2004-08-31 17:03:59 +09:00
+++ 1.28/arch/mips/kernel/sysirix.c	2004-10-19 14:26:36 +09:00
@@ -128,16 +128,21 @@
 		if (value > RLIM_INFINITY)
 			value = RLIM_INFINITY;
 		if (capable(CAP_SYS_ADMIN)) {
-			current->rlim[RLIMIT_STACK].rlim_max =
-				current->rlim[RLIMIT_STACK].rlim_cur = value;
+			task_lock(current->group_leader);
+			current->signal->rlim[RLIMIT_STACK].rlim_max =
+				current->signal->rlim[RLIMIT_STACK].rlim_cur = value;
+			task_unlock(current->group_leader);
 			error = value;
 			break;
 		}
-		if (value > current->rlim[RLIMIT_STACK].rlim_max) {
+		task_lock(current->group_leader);
+		if (value > current->signal->rlim[RLIMIT_STACK].rlim_max) {
 			error = -EINVAL;
+			task_unlock(current->group_leader);
 			break;
 		}
-		current->rlim[RLIMIT_STACK].rlim_cur = value;
+		current->signal->rlim[RLIMIT_STACK].rlim_cur = value;
+		task_unlock(current->group_leader);
 		error = value;
 		break;
 	}
@@ -145,7 +150,7 @@
 	case PR_GETSTACKSIZE:
 		printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n",
 		       current->comm, current->pid);
-		error = current->rlim[RLIMIT_STACK].rlim_cur;
+		error = current->signal->rlim[RLIMIT_STACK].rlim_cur;
 		break;
 
 	case PR_MAXPPROCS:
@@ -558,7 +563,7 @@
 	/*
 	 * Check against rlimit and stack..
 	 */
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (brk - mm->end_code > rlim) {
@@ -2132,7 +2137,7 @@
 		retval = -EINVAL;
 		goto out;
 #endif
-		retval = current->rlim[RLIMIT_NOFILE].rlim_cur;
+		retval = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
 		goto out;
 
 	case 5:
===== arch/ia64/kernel/perfmon.c 1.94 vs 1.95 =====
--- 1.94/arch/ia64/kernel/perfmon.c	2004-10-06 03:27:39 +09:00
+++ 1.95/arch/ia64/kernel/perfmon.c	2004-10-19 14:28:03 +09:00
@@ -2287,7 +2287,8 @@
 	 * if ((mm->total_vm << PAGE_SHIFT) + len> task->rlim[RLIMIT_AS].rlim_cur)
 	 * 	return -ENOMEM;
 	 */
-	if (size > task->rlim[RLIMIT_MEMLOCK].rlim_cur) return -ENOMEM;
+	if (size > task->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
+		return -EAGAIN;
 
 	/*
 	 * We do the easy to undo allocations first.
===== security/selinux/hooks.c 1.63 vs 1.64 =====
--- 1.63/security/selinux/hooks.c	2004-10-14 13:08:29 +09:00
+++ 1.64/security/selinux/hooks.c	2004-10-19 14:26:36 +09:00
@@ -1909,8 +1909,8 @@
 				  PROCESS__RLIMITINH, NULL, NULL);
 		if (rc) {
 			for (i = 0; i < RLIM_NLIMITS; i++) {
-				rlim = current->rlim + i;
-				initrlim = init_task.rlim+i;
+				rlim = current->signal->rlim + i;
+				initrlim = init_task.signal->rlim+i;
 				rlim->rlim_cur = min(rlim->rlim_max,initrlim->rlim_cur);
 			}
 		}
@@ -2699,7 +2699,7 @@
 
 static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
 {
-	struct rlimit *old_rlim = current->rlim + resource;
+	struct rlimit *old_rlim = current->signal->rlim + resource;
 	int rc;
 
 	rc = secondary_ops->task_setrlimit(resource, new_rlim);
===== arch/ia64/mm/fault.c 1.21 vs 1.22 =====
--- 1.21/arch/ia64/mm/fault.c	2004-10-06 03:27:40 +09:00
+++ 1.22/arch/ia64/mm/fault.c	2004-10-19 14:26:36 +09:00
@@ -32,8 +32,8 @@
 	unsigned long grow;
 
 	grow = PAGE_SIZE >> PAGE_SHIFT;
-	if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur
-	    || (((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur))
+	if (address - vma->vm_start > current->signal->rlim[RLIMIT_STACK].rlim_cur
+	    || (((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->signal->rlim[RLIMIT_AS].rlim_cur))
 		return -ENOMEM;
 	vma->vm_end += PAGE_SIZE;
 	vma->vm_mm->total_vm += grow;
===== arch/x86_64/ia32/ia32_aout.c 1.4 vs 1.5 =====
--- 1.4/arch/x86_64/ia32/ia32_aout.c	2004-07-14 10:30:01 +09:00
+++ 1.5/arch/x86_64/ia32/ia32_aout.c	2004-10-19 14:26:36 +09:00
@@ -168,12 +168,12 @@
 /* If the size of the dump file exceeds the rlimit, then see what would happen
    if we wrote the stack, but not the data area.  */
 	if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
+	    current->signal->rlim[RLIMIT_CORE].rlim_cur)
 		dump.u_dsize = 0;
 
 /* Make sure we have enough room to write the stack and data areas. */
 	if ((dump.u_ssize+1) * PAGE_SIZE >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
+	    current->signal->rlim[RLIMIT_CORE].rlim_cur)
 		dump.u_ssize = 0;
 
 /* make sure we actually have a data and stack area to dump */
@@ -281,7 +281,7 @@
 	 * size limits imposed on them by creating programs with large
 	 * arrays in the data or bss.
 	 */
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim >= RLIM_INFINITY)
 		rlim = ~0;
 	if (ex.a_data + ex.a_bss > rlim)
===== arch/mips/kernel/irixelf.c 1.11 vs 1.12 =====
--- 1.11/arch/mips/kernel/irixelf.c	2004-05-10 20:25:30 +09:00
+++ 1.12/arch/mips/kernel/irixelf.c	2004-10-19 14:26:36 +09:00
@@ -1055,7 +1055,7 @@
 	struct vm_area_struct *vma;
 	struct elfhdr elf;
 	off_t offset = 0, dataoff;
-	int limit = current->rlim[RLIMIT_CORE].rlim_cur;
+	int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
 	int numnote = 4;
 	struct memelfnote notes[4];
 	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
===== mm/filemap.c 1.274 vs 1.275 =====
--- 1.274/mm/filemap.c	2004-09-12 00:50:30 +09:00
+++ 1.275/mm/filemap.c	2004-10-19 14:28:19 +09:00
@@ -1804,7 +1804,7 @@
 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->rlim[RLIMIT_FSIZE].rlim_cur;
+	unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
 
         if (unlikely(*pos < 0))
                 return -EINVAL;

Reply to: