From davidn@labs.usn.blaze.net.au  Mon Jan 20 07:10:43 1997
Received: from labs.usn.blaze.net.au (labs.usn.blaze.net.au [203.17.53.30])
          by freefall.freebsd.org (8.8.4/8.8.4) with ESMTP id HAA05666
          for <FreeBSD-gnats-submit@freebsd.org>; Mon, 20 Jan 1997 07:10:37 -0800 (PST)
Received: (from davidn@localhost)
          by labs.usn.blaze.net.au (8.8.4/8.8.4)
	  id CAA01575; Tue, 21 Jan 1997 02:10:34 +1100 (EST)
Message-Id: <199701201510.CAA01575@labs.usn.blaze.net.au>
Date: Tue, 21 Jan 1997 02:10:34 +1100 (EST)
From: David Nugent <davidn@unique.usn.blaze.net.au>
Reply-To: davidn@unique.usn.blaze.net.au
To: FreeBSD-gnats-submit@freebsd.org
Subject: filesize-cur resource limit reset to "infinity"
X-Send-Pr-Version: 3.2

>Number:         2535
>Category:       kern
>Synopsis:       filesize-cur resource limit reset to "infinity"
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    davidn
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 20 07:20:01 PST 1997
>Closed-Date:    Wed Jan 22 03:41:07 EST 1997
>Last-Modified:  Wed Jan 22 03:43:15 EST 1997
>Originator:     David Nugent - davidn@blaze.net.au
>Release:        FreeBSD 3.0-CURRENT i386
>Organization:
Unique Computing, Melbourne, Australia
>Environment:

	Current (since login.conf support enabled).

>Description:

	I'm hoping that this will be fixed by some future patches by
	Bruce, but I'm logging it here just in case it isn't. :)

	Enable resource settings via /etc/login.conf as usual.
	Resources are all set by login(1) correctly, but after
	the first program is run by the shell, the "filesize"
	soft/current limit is reset to "infinite". This behaviour
	is bizarre, to say the least.

>How-To-Repeat:

	Set resource limits in /etc/login.conf, such as:

		:cputime=infinity:\
		:filesize=64M:\
		:datasize=8M:\
		:stacksize=8M:\
		:coredumpsize=8M:\
		:memoryuse=8M:\
		:memorylocked=4M:\
		:maxproc=20:\
		:openfiles=20:\
		:coredumpsize=infinity:\

	Using tcsh in this example (same thing occurs with any
	shell), insert the following into /etc/csh.login BEFORE
	any external command is run, either directly or by backtick.

	echo hard limits:
	limit -h
	echo soft limits:
	limit

	Insert the same AFTER the first external command is run.

	Results:

	BEFORE                           AFTER

	hard limits:

	cputime 	unlimited	cputime         unlimited
	filesize	10240 kbytes	filesize        10240 kbytes
	datasize	8192 kbytes	datasize        8192 kbytes 
	stacksize	8192 kbytes	stacksize       8192 kbytes 
	coredumpsize	8192 kbytes	coredumpsize    8192 kbytes 
	memoryuse	8192 kbytes	memoryuse       8192 kbytes 
	memorylocked	4096 kbytes	memorylocked    4096 kbytes 
	maxproc 	20		maxproc         20
	openfiles	20		openfiles       20

	soft limits:

	cputime 	unlimited	cputime         unlimited
     |	filesize        10240 kbytes	filesize        unlimited
	datasize	8192 kbytes	datasize        8192 kbytes	
	stacksize	8192 kbytes	stacksize       8192 kbytes
	coredumpsize	8192 kbytes	coredumpsize    8192 kbytes
	memoryuse	8192 kbytes	memoryuse       8192 kbytes
	memorylocked	4096 kbytes	memorylocked    4096 kbytes
	maxproc 	20		maxproc         20
	openfiles	20		openfiles       20

	The vertical bar to the left highlights the mysterious change.

	Aside: can soft limits be *validly* set higher than hard limits
	like this? I wouldn't have thought so.


>Fix:
	
	Remove the following line in sys/kern/kern_exit.c? I have no
	idea why this line is even there in the first place. :-)
	Can anyone explain why?

--- kern_exit.c.orig	Wed Jan 15 14:55:26 1997
+++ kern_exit.c	Tue Jan 21 01:51:26 1997
@@ -222,7 +222,7 @@
 		sp->s_leader = NULL;
 	}
 	fixjobc(p, p->p_pgrp, 0);
-	p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
+     /* p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; */
 	(void)acct_process(p);
 #ifdef KTRACE
 	/*

	My first guess is that it appears to be related to the process
	accounting database so that the data file will not be
	stopped from growing by virtue of the filesize resource limit
	for the exiting process, which suggests that this fix is wrong,
	and perhaps the real fix would require saving and restoring this
	resource limit around the call to acct_process(). I'll leave
	that up to someone knows this code better than I do.

	Alternative (assuming the above paragraph/guess is correct):

--- kern_exit.c.orig	Wed Jan 15 14:55:26 1997
+++ kern_exit.c	Tue Jan 21 01:57:27 1997
@@ -120,6 +120,7 @@
 	register struct proc *q, *nq;
 	register struct vmspace *vm;
 	ele_p ep = exit_list;
+	rlim_t fsize_cur;
 
 	if (p->p_pid == 1) {
 		printf("init died (signal %d, exit %d)\n",
@@ -222,8 +223,10 @@
 		sp->s_leader = NULL;
 	}
 	fixjobc(p, p->p_pgrp, 0);
-	p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
+	fsize_cur = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
+       p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 	(void)acct_process(p);
+       p->p_rlimit[RLIMIT_FSIZE].rlim_cur = fsize_cur;
 #ifdef KTRACE
 	/*
 	 * release trace file

	Should the hard limit be given similar treatment here?

	It also occurs to me that the wrong p->p_rlimit[RLIMIT_FSIZE].rlim_cur
	may be being used, which makes either fix incorrect, and the
	desired effect of this line ineffective. This function appears
	to be the kernel's exit process handler, so I have no idea why
	the CALLING processes resources are being modified and not those
	that apply to the the exiting process which I assume it should be...

	Help!  :-)


>Release-Note:
>Audit-Trail:

From: davidn@unique.usn.blaze.net.au (David Nugent)
To: FreeBSD-gnats-submit@freebsd.org
Cc:  Subject: Re: kern/2535: filesize-cur resource limit reset to "infinity"
Date: Tue, 21 Jan 1997 03:04:05 +1100

 I wrote:
 > 	My first guess is that it appears to be related to the process
 > 	accounting database so that the data file will not be
 > 	stopped from growing by virtue of the filesize resource limit
 > 	for the exiting process, which suggests that this fix is wrong,
 > 	and perhaps the real fix would require saving and restoring this
 > 	resource limit around the call to acct_process(). I'll leave
 > 	that up to someone knows this code better than I do.
 > 
 > 	Alternative (assuming the above paragraph/guess is correct):
 > 
 > --- kern_exit.c.orig	Wed Jan 15 14:55:26 1997
 > +++ kern_exit.c	Tue Jan 21 01:57:27 1997
 > @@ -120,6 +120,7 @@
 >  	register struct proc *q, *nq;
 >  	register struct vmspace *vm;
 >  	ele_p ep = exit_list;
 > +	rlim_t fsize_cur;
 >  
 >  	if (p->p_pid == 1) {
 >  		printf("init died (signal %d, exit %d)\n",
 > @@ -222,8 +223,10 @@
 >  		sp->s_leader = NULL;
 >  	}
 >  	fixjobc(p, p->p_pgrp, 0);
 > -	p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 > +	fsize_cur = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
 > +       p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 >  	(void)acct_process(p);
 > +       p->p_rlimit[RLIMIT_FSIZE].rlim_cur = fsize_cur;
 >  #ifdef KTRACE
 >  	/*
 >  	 * release trace file
 
 Just to confirm that the above does in fact "fix" the problem.
 However, my feeling is that this is not the correct fix, since
 the way I read this code is that it is supposed to be setting
 the soft RLIMIT_FSIZE for the exiting process, not the parent
 process. How this comes to be, I have no idea, unless somehow
 the p_limit element in the exiting proc points to its parent
 at this point.
 
 
 Regards,
 
 David Nugent - Unique Computing Pty Ltd - Melbourne, Australia
 Voice +61-3-9791-9547  Data/BBS +61-3-9792-3507  3:632/348@fidonet
 davidn@freebsd.org davidn@blaze.net.au http://www.blaze.net.au/~davidn/

From: Bruce Evans <bde@zeta.org.au>
To: davidn@unique.usn.blaze.net.au, FreeBSD-gnats-submit@FreeBSD.org
Cc:  Subject: Re: kern/2535: filesize-cur resource limit reset to "infinity"
Date: Tue, 21 Jan 1997 04:52:38 +1100

 >>Fix:
 >	
 >	Remove the following line in sys/kern/kern_exit.c? I have no
 >	idea why this line is even there in the first place. :-)
 >	Can anyone explain why?
 >
 >--- kern_exit.c.orig	Wed Jan 15 14:55:26 1997
 >+++ kern_exit.c	Tue Jan 21 01:51:26 1997
 >@@ -222,7 +222,7 @@
 > 		sp->s_leader = NULL;
 > 	}
 > 	fixjobc(p, p->p_pgrp, 0);
 >-	p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 >+     /* p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; */
 
 rlimits are copy on write (implemented in software; grep for p_limit
 in kern_fork.c and kern_resource.c).  The above code neglects to
 duplicate the struct before writing to it.
 
 Bruce

From: davidn@unique.usn.blaze.net.au (David Nugent)
To: bde@zeta.org.au (Bruce Evans)
Cc: FreeBSD-gnats-submit@FreeBSD.org
Subject: Re: kern/2535: filesize-cur resource limit reset to "infinity"
Date: Tue, 21 Jan 1997 12:54:14 +1100

 Bruce Evans writes:
 > >+     /* p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; */
 > 
 > rlimits are copy on write (implemented in software; grep for p_limit
 > in kern_fork.c and kern_resource.c).  The above code neglects to
 > duplicate the struct before writing to it.
 
 Suddenly things make sense - thanks Bruce. :-)
 
 Is this patch the correct fix?
 
 --- kern_exit.c.orig	Wed Jan 15 14:55:26 1997
 +++ kern_exit.c	Tue Jan 21 12:48:57 1997
 @@ -222,6 +222,10 @@
  		sp->s_leader = NULL;
  	}
  	fixjobc(p, p->p_pgrp, 0);
 +	if (p->p_limit->p_refcnt > 1 && p->p_limit->p_lflags & PL_SHAREMOD) {
 +		p->p_limit->p_refcnt--;
 +		p->p_limit = limcopy(p->p_limit);
 +	}
  	p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
  	(void)acct_process(p);
  #ifdef KTRACE
 
 
 Regards,
 
 David Nugent - Unique Computing Pty Ltd - Melbourne, Australia
 Voice +61-3-9791-9547  Data/BBS +61-3-9792-3507  3:632/348@fidonet
 davidn@freebsd.org davidn@blaze.net.au http://www.blaze.net.au/~davidn/
State-Changed-From-To: open->closed 
State-Changed-By: davidn 
State-Changed-When: Wed Jan 22 03:41:07 EST 1997 
State-Changed-Why:  
Fixed in both -current and RELENG_2_2 branch in kern/kern_exit.c, copy 
process resources before modification. 


Responsible-Changed-From-To: freebsd-bugs->davidn 
Responsible-Changed-By: davidn 
Responsible-Changed-When: Wed Jan 22 03:41:07 EST 1997 
Responsible-Changed-Why:  
Fixed by my commit. 
>Unformatted:
