[comp.bugs.sys5] ulimit -- You don't need sources!

duncan@rtp48.dg.com (W. Lee Duncan) (05/03/89)

In article <8305@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell)
writes:
>In article <545@aurora.AthabascaU.CA> lyndon@nexus.ca (Lyndon Nerenberg)
>writes:
>
>>>It is not difficult at all for the administrator to set a higher
>>>ulimit for users that have a legitimate need, ESPECIALLY is you have
>>>source to the login program.
>
>>That's a pretty damn big ESPECIALLY. ... [more complaining]
>
>Or perhaps an OS that provides per-user disk quotas (and a machine
>to run it on.. [notice the lack of a smiley here])
>
[ much more complaining and arguing]

I suppose all have already though of this, but you don't need sources
to modify login (or any other program).

Simply move /bin/login to, e.g. /usr/lib/old_login (and make it non-setuid).
Then, create a new /bin/login program (which will be setuid to root):

main(argc, argv)
int     argc;
char    *argv[];
{
        ulimit(SOME_BIG_NUMBER);            /* set some big ulimit */
        execv("/usr/lib/old_login", argv);  /* call the orig. login */

        (void)fprintf(stderr, "Oh oh! shouldn't reach here!\n");
        exit(ENOUSEINLIFE)
}

Note that, if you wish to have some sort of user database that's used
to find the ulimit per user, and you access that here (instead of just
setting the ulimit to a large value) you can get in to trouble (email
me if you don't know what I mean here).

Just use common sense and testing, and this should work fine.

I have used this approach for several things, including having "uucp"
check user names in a database before allowing access, and
single-threading a "troff"/laser printer.

Sorry about the tone -- Just thought some helpful information might
be called for.

grs@cbnews.ATT.COM (gregg.r.siegfried) (05/04/89)

In article <5627@xyzzy.UUCP> duncan@rtp48.dg.com (W. Lee Duncan) writes:
>Simply move /bin/login to, e.g. /usr/lib/old_login (and make it non-setuid).
>Then, create a new /bin/login program (which will be setuid to root):

[ C program that raises ulimit and invokes login mostly deleted ]

>        ulimit(SOME_BIG_NUMBER);            /* set some big ulimit */
         ulimit(2,SOME_BIG_NUMBER);          /* would probably work better */

Aside from the minor correction above, this approach does work.  It does
have some minor tradeoffs, however.  The problem I've always had with this
is that all user processes (or the ones in your "database") have a higher
ulimit, while all the non-login processes retain the 1K ulimit.  If you
use the at(1) command (is "at(1) command" redundant BTW? :-), you'll have
to alias "at" to "ulimit 2048;/usr/bin/at $*" since at tries to reproduce
the environment of the user submitting the job (oohh that sounds IBMish)
exactly, and because your at job is running with the cron daemon's 1 
Meg ulimit, it will fail in its attempt to raise it to SOME_LARGE_NUMBER,
and the only work it will do is send you a mail message reading
something like "ulimit: bad number".  I was always a stickler for 
consistency and used the CDLIMIT define in sys/param.h to raise the 
thing globally.  But, I guess a lot of people don't have that luxury.

The last time I observed anyone using a front end to login to raise
the ulimit, and thus the at(1) problem, was with SVR2, but that would
make sense because starting with SVR3, ulimit became a tunable, and 
people quit thinking of silly things to do to raise it.

It was a fairly easy to fix cron to stop the unpleasant at behavior,
as I recall, but in practice most people stuck with raising the 
ulimit in /etc/rc before cron was started.  Yeah!  Raise it in
TWO places.  Now THAT's elegant. ;-)

Gregg Siegfried
Speaking for myself, of course..

grs@cbnews.ATT.COM (gregg.r.siegfried) (05/04/89)

In article <6218@cbnews.ATT.COM> I write:
>ulimit, while all the non-login processes retain the 1K ulimit.  If you
                                                      ^^
Naturally, I mean 1 Meg here, rather than 1K.  Following up my own
articles is usually something I like to avoid.  There isn't often
a whole lot you can take issue with that isn't better discussed over
a beer.  But, if people can do it for a silly .signature, I can
certainly rectify a glaring semantic error. :-)

Gregg
grs@cblph.att.com

lyndon@cs.AthabascaU.CA (Lyndon Nerenberg) (05/04/89)

In article <5627@xyzzy.UUCP> duncan@rtp48.dg.com (W. Lee Duncan) writes:
>I suppose all have already though of this, but you don't need sources
>to modify login (or any other program).
>
>Simply move /bin/login to, e.g. /usr/lib/old_login (and make it non-setuid).
>Then, create a new /bin/login program (which will be setuid to root):

One problem with this is that cron jobs don't go through login. Yes I can
add an explicit ulimit command to the command lines in cron, just as I
can add wrappers around login. The fact that I have to do this on such
a global scale argues that perhaps this limit shouldn't be there in the
first place ...

-- 
Lyndon Nerenberg   Computing Services   Athabasca University
{alberta,attvcr,ncc}!atha!lyndon  ||  lyndon@nexus.ca

pss@unh.UUCP (Paul S. Sawyer) (05/05/89)

In article <5627@xyzzy.UUCP>, duncan@rtp48.dg.com (W. Lee Duncan) writes:
> I suppose all have already though of this, but you don't need sources
> to modify login (or any other program).
> 
> Simply move /bin/login to, e.g. /usr/lib/old_login (and make it non-setuid).
> Then, create a new /bin/login program (which will be setuid to root):
> 
...
> 	/* set some big ulimit */
> 	/* call the orig. login */
...
Since INIT is running as root anyway, it can set the ulimit and then call
getty.  E.g., in /etc/inittab:

t000:2:respawn:/etc/gettyup tty000 9600

	where /etc/gettyup is:

ulimit 100000; exec /etc/getty $* 

This lets you put the higher limit on only the lines you wish.  Some versions
of init let you put the whole thing in the inittab.  (mine wouldn't,
back when I first did this)


> Note that, if you wish to have some sort of user database that's used
> to find the ulimit per user, and you access that here (instead of just
> setting the ulimit to a large value) you can get in to trouble (email
> me if you don't know what I mean here).

Yes, so why not UP the ulimit as above for EVERYBODY (as above), then do
user specific stuff within /etc/profile - - anybody can set the ulimit down;
for users you trust, or will trust someday, put it in their original
$HOME/.profile  (of course, I am speaking Sys5 and /bin/sh here, but
that's where this problem comes from in the first place... B-)

> Just use common sense and testing, and this should work fine.

(But this IS SysV !  ;-)  ;-)  ;-)



-- 
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Paul S. Sawyer              uunet!unh!unhtel!paul     paul@unhtel.UUCP
UNH Telecommunications
Durham, NH  03824-3523      VOX: 603-862-3262         FAX: 603-862-2030

brooks@corpane.UUCP (David E. Brooks Jr) (05/05/89)

In article <6218@cbnews.ATT.COM>,
   grs@cbnews.ATT.COM (gregg.r.siegfried) writes:
> The problem I've always had with this
> is that all user processes (or the ones in your "database") have a higher
> ulimit, while all the non-login processes retain the 1K ulimit.

I saw a posting not that long ago where someone (I wish I could remember
who) did a similar process using init.  This way, all processes (which are
sub-processes of init, eventually) would have the higher ulimit.  It would
seem to me that combining the two methods would provide a reasonably powerful
method of controlling file sizes, since there is no reason that the pseudo-
login couldn't lower the ulimit.

> Gregg Siegfried
> Speaking for myself, of course..

-- 
David E. Brooks Jr                           UUCP :  ...!ddsw1!corpane!brooks
Corpane Industries Incorporated                      ...!ukma!corpane!brooks
10100 Bluegrass Parkway                      Phone:  +1 502 491 4433 x122
Louisville, KY  40299                        Quote:  printf("%c",34)

scl@virginia.acc.virginia.edu (Steve Losen) (05/05/89)

In article <562@aurora.AthabascaU.CA> lyndon@nexus.ca writes:
%
%One problem with this is that cron jobs don't go through login. Yes I can
%add an explicit ulimit command to the command lines in cron, just as I
%can add wrappers around login. The fact that I have to do this on such
%a global scale argues that perhaps this limit shouldn't be there in the
%first place ...

Ok -- so the obvious solution is to write a new /etc/init that
sets the ulimit and then execs the real init, "/etc/init.real".
Then every process on the system inherits the big ulimit.
(I haven't had the guts to try this, however)
-- 
Steve Losen     scl@virginia.edu
University of Virginia Academic Computing Center

jfh@rpp386.Dallas.TX.US (John F. Haugh II) (05/06/89)

In article <1153@unh.UUCP> pss@unh.UUCP (Paul S. Sawyer) writes:
>In article <5627@xyzzy.UUCP>, duncan@rtp48.dg.com (W. Lee Duncan) writes:
>> Simply move /bin/login to, e.g. /usr/lib/old_login (and make it non-setuid).
>> Then, create a new /bin/login program (which will be setuid to root):
>> 
>Since INIT is running as root anyway, it can set the ulimit and then call
>getty.  E.g., in /etc/inittab:
>
>t000:2:respawn:/etc/gettyup tty000 9600

No - since UNIX forks init directly out of the kernel as root, why
not step in there and raise the ulimit before the real init gets to
run?

Now you only have one wrapper instead of all the getty, login, cron,
and what-else-have-you versions.

prc@erbe.se (Robert Claeson) (05/06/89)

In article <2408@virginia.acc.virginia.edu>, scl@virginia.acc.virginia.edu (Steve Losen) writes:

> Ok -- so the obvious solution is to write a new /etc/init that
> sets the ulimit and then execs the real init, "/etc/init.real".
> Then every process on the system inherits the big ulimit.

I'd reconfigure the kernel with a larger ulimit instead.
-- 
Robert Claeson, ERBE DATA AB, P.O. Box 77, S-175 22 Jarfalla, Sweden
Tel: +46 (0)758-202 50  Fax: +46 (0)758-197 20
EUnet:   rclaeson@ERBE.SE               uucp:   {uunet,enea}!erbe.se!rclaeson
ARPAnet: rclaeson%ERBE.SE@uunet.UU.NET  BITNET: rclaeson@ERBE.SE

rjd@occrsh.ATT.COM (Randy_Davis) (05/08/89)

In article <16463@rpp386.Dallas.TX.US> jfh@rpp386.Dallas.TX.US (John F. Haugh II) writes:
|No - since UNIX forks init directly out of the kernel as root, why
|not step in there and raise the ulimit before the real init gets to
|run?
|
|Now you only have one wrapper instead of all the getty, login, cron,
|and what-else-have-you versions.

  Wrong - all of these schemes to change the ulimit BEFORE the login program
is run from the normal sequence init-getty-login-shell will not work!!!

  If the ulimit is set to some high number before login is run (and, in fact it
IS), such as in the kernel, and if you are running a System V version before the
ulimit was settable in the /etc/master.d/kernel file, the ulimit for logins is
last set in the /bin/login program.  So, setting your kernel, your init, or
your getty ulimit higher would be fine, yet as soon as a person logs in and
run this (pre-3.0) /bin/login, the line "ulimit(2,<low number>);" (near line
248 in the source if you are curious) would be implemented for all non-root
logins, and you are back to where you started.

  To solve the problem on pre-3.0 release AT&T System V Unix operating systems
for user logins, you must change the login program.  On 3.0 and later releases,
it is a tunable parameter in the /etc/master.d/kernel file.  To change it for
non-user process (cron, etc..), a change in the /etc/rc script might be
sufficient.

Randy Davis					UUCP: ...(att!)ocrjd!randy
						      ...(att!)occrsh!rjd

ian@sibyl.eleceng.ua.OZ (Ian Dall) (05/09/89)

In article <562@aurora.AthabascaU.CA> lyndon@nexus.ca writes:
>In article <5627@xyzzy.UUCP> duncan@rtp48.dg.com (W. Lee Duncan) writes:
>>I suppose all have already though of this, but you don't need sources
>>to modify login (or any other program).
>>
>>Simply move /bin/login to, e.g. /usr/lib/old_login (and make it non-setuid).
>>Then, create a new /bin/login program (which will be setuid to root):
>
>One problem with this is that cron jobs don't go through login. Yes I can
>add an explicit ulimit command to the command lines in cron, just as I
>can add wrappers around login. The fact that I have to do this on such
>a global scale argues that perhaps this limit shouldn't be there in the
>first place ...

If you want to defeat ulimit once and for all put the wrapper around
init. This is so small I will include it here

#define BIGNUM 0x204090
main(argc,argv) char **argv;
{ ulimit(2,BIGNUM); execv("/etc/init.real", argv); }

I can't quite remember what the rationale if any was for my choice of BIGNUM.
This does not to be suid because, of course, init runs with euid 0.

-- 
Ian Dall     life (n). A sexually transmitted disease which afflicts
                       some people more severely than others.       

kent@ssbell.UUCP (Kent Landfield) (05/10/89)

In article <697@occrsh.ATT.COM> rjd@occrsh.UUCP (Randy_Davis) writes:
>
>  Wrong - all of these schemes to change the ulimit BEFORE the login program
>is run from the normal sequence init-getty-login-shell will not work!!!
>
>  If the ulimit is set to some high number before login is run (and, in fact it
>IS), such as in the kernel, and if you are running a System V version before the
>ulimit was settable in the /etc/master.d/kernel file, the ulimit for logins is
>last set in the /bin/login program.  So, setting your kernel, your init, or
>your getty ulimit higher would be fine, yet as soon as a person logs in and
>run this (pre-3.0) /bin/login, the line "ulimit(2,<low number>);" (near line
>248 in the source if you are curious) would be implemented for all non-root
>logins, and you are back to where you started.

I have a System V.2 source licence direct from AT&T. I examined the
source to login and found that this just was *not* true. I don't know
what version you are looking at but the System V.2 version of login that
your company distributed does not have any reference to ulimit in it 
anywhere.

The ulimit for users is initially set in uts/machine/os/main.c with a 
line like: 
u.u_limit = CDLIMIT;

There are NO references to ulimit in V.2 init, V.2 getty or V.2 login. 
The wrapper ideas *can* work, *do* work, and *are* working at a number 
of sites that I know about. This is a kludge to get around a "feeeature"
that in my opinion is more trouble than its worth.

>Randy Davis					UUCP: ...(att!)ocrjd!randy

This sounds like a CM problem to me.. Which Version, What Version, 
Whose's Version, Your Version. :-)

			-Kent+
---
Kent Landfield               UUCP:     kent@ssbell
Sterling Software FSG/IMD    INTERNET: kent%ssbell.uucp@uunet.uu.net
1404 Ft. Crook Rd. South     Phone:    (402) 291-8300 
Bellevue, NE. 68005-2969     FAX:      (402) 291-4362

cgh018@tijc02.UUCP (Calvin Hayden ) (05/10/89)

> In article <16463@rpp386.Dallas.TX.US> jfh@rpp386.Dallas.TX.US (John F. Haugh II) writes:
> |No - since UNIX forks init directly out of the kernel as root, why
> |not step in there and raise the ulimit before the real init gets to
> |run?
>   Wrong - all of these schemes to change the ulimit BEFORE the login program
> is run from the normal sequence init-getty-login-shell will not work!!!
> 
>   If the ulimit is set to some high number before login is run (and, in fact it
> IS), such as in the kernel, and if you are running a System V version before the
> ulimit was settable in the /etc/master.d/kernel file, the ulimit for logins is
> last set in the /bin/login program.  So, setting your kernel, your init, or
> your getty ulimit higher would be fine, yet as soon as a person logs in and
> run this (pre-3.0) /bin/login, the line "ulimit(2,<low number>);" (near line
> 248 in the source if you are curious) would be implemented for all non-root
> logins, and you are back to where you started.
> 
>   To solve the problem on pre-3.0 release AT&T System V Unix operating systems
> for user logins, you must change the login program.  On 3.0 and later releases,
> it is a tunable parameter in the /etc/master.d/kernel file.  To change it for
> non-user process (cron, etc..), a change in the /etc/rc script might be
> sufficient.
> 
> Randy Davis					UUCP: ...(att!)ocrjd!randy
> 						      ...(att!)occrsh!rjd

Not necessarily true.  We're running AT&T Sys V Rel 2 Ver 2, and the 
login program does not contain the "ulimit(....)" line.  This version
was ported to our Vax 8600 architecture, so it is possible that this was
altered during the port.  On our system, the default ulimit 
is defined in param.h as CDLIMIT  (L1<<12) on our system.  On
some other test systems here based on SysV R2 V2, an entry
was made in one of the bootup files -- something to the effect of adding
ulimit big# to the /etc/rc file, and it worked for all logins -- everyone
logging in received the ulimit defined in the /etc/rc file.

Calvin

dpi@loft386.UUCP (Douglas P. Ingraham) (05/10/89)

Page 43 of the SYS V 386 Release 3.2 RELEASE NOTES is quite clear on how
to change ULIMIT for logins.  I suspect versions for other systems also
allow ULIMIT to be changed in the file /etc/default/login.

Doug Ingraham

dpi@loft386.UUCP
bigtex!loft386!dpi

pss@unh.UUCP (Paul S. Sawyer) (05/11/89)

In article <697@occrsh.ATT.COM>, rjd@occrsh.ATT.COM (Randy_Davis) writes:
>   Wrong - all of these schemes to change the ulimit BEFORE the login program
> is run from the normal sequence init-getty-login-shell will not work!!!

But - - my scheme to raise the ulimit before getty (as I recently posted)
DOES work, and HAS been working all along! (or I would not be using it!   B-)  
This is System V.2.1.1; it also worked on 2.0.? (3B5).


>   If the ulimit is set to some high number before login is run (and, in fact it
> IS), such as in the kernel, and if you are running a System V version before the
> ulimit was settable in the /etc/master.d/kernel file, the ulimit for logins is
> last set in the /bin/login program.  So, setting your kernel, your init, or
> your getty ulimit higher would be fine, yet as soon as a person logs in and
> run this (pre-3.0) /bin/login, the line "ulimit(2,<low number>);" (near line
> 248 in the source if you are curious) would be implemented for all non-root
> logins, and you are back to where you started.

I AM curious.  But AT&T has not seen fit to include the source for
/bin/login to binary licensees just because they are curious.  Since login
runs suid root, and is called by init running as root, does it really do
that based on login name, or user id?  I suspect the latter... hmmm, I
just did a "exec login paul" and kept my 100,000 block ulimit, so it isn't
real user id...  or, what is <low number>? if I don't set it up, it seems to
be 2048... or my system is broke, but PLEASE DON'T FIX IT!!

>   To solve the problem on pre-3.0 release AT&T System V Unix operating systems
> for user logins, you must change the login program.  On 3.0 and later releases,

If I must, I must.  This seems to imply that AT&T must start supplying source
code for /bin/login and several other files important to a customer's use
of the system.  This falls far short of our needing to become source
licensees.  The initial discussion, I believe, was how to get around the
ulimit (which some consider good, some consider evil) if you don't have
source.  (Anything is possible if the Source is with you...  B-)

> it is a tunable parameter in the /etc/master.d/kernel file.  To change it for
> non-user process (cron, etc..), a change in the /etc/rc script might be
> sufficient.

This is a good idea - - would it cure the "at" problem?


> Randy Davis					UUCP: ...(att!)ocrjd!randy
> 						      ...(att!)occrsh!rjd


-- 
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Paul S. Sawyer              uunet!unh!unhtel!paul     paul@unhtel.UUCP
UNH Telecommunications
Durham, NH  03824-3523      VOX: 603-862-3262         FAX: 603-862-2030

kent@happym.wa.com (Kent Forschmiedt) (05/11/89)

People have been arguing about the pros and cons of putting a wrapper
around login to fix the silly ulimit problem.  People have observed
that fixing login does not fix cron.

If you put a wrapper around init, it will fix everything.  Just be careful.
-- 
 kent@happym.wa.com, tikal!camco!happym!kent, Happy Man Corp 206-282-9598

ian@sibyl.eleceng.ua.OZ (Ian Dall) (05/11/89)

In article <697@occrsh.ATT.COM> rjd@occrsh.UUCP (Randy_Davis) writes:
->In article <16463@rpp386.Dallas.TX.US> jfh@rpp386.Dallas.TX.US (John F. Haugh II) writes:
->|No - since UNIX forks init directly out of the kernel as root, why
->|not step in there and raise the ulimit before the real init gets to
->|run?
->|
->|Now you only have one wrapper instead of all the getty, login, cron,
->|and what-else-have-you versions.
->
->  Wrong - all of these schemes to change the ulimit BEFORE the login program
->is run from the normal sequence init-getty-login-shell will not work!!!
->
->  If the ulimit is set to some high number before login is run (and, in fact it
->IS), such as in the kernel, and if you are running a System V version before the
->ulimit was settable in the /etc/master.d/kernel file, the ulimit for logins is
->last set in the /bin/login program.  So, setting your kernel, your init, or
->your getty ulimit higher would be fine, yet as soon as a person logs in and
->run this (pre-3.0) /bin/login, the line "ulimit(2,<low number>);" (near line
->248 in the source if you are curious) would be implemented for all non-root
->logins, and you are back to where you started.

Curious. I don't have the sources but I have to believe you do. I can
assure you that on this Sys V.2.2 ulimit is NOT set by login and that
the init hack does work (I have been running it for years).


-- 
Ian Dall     life (n). A sexually transmitted disease which afflicts
                       some people more severely than others.       

dave@pmafire.UUCP (Dave Remien) (05/14/89)

In article <476@loft386.UUCP> dpi@loft386.UUCP (Douglas P. Ingraham) writes:
>
>Page 43 of the SYS V 386 Release 3.2 RELEASE NOTES is quite clear on how
>to change ULIMIT for logins.  I suspect versions for other systems also
>allow ULIMIT to be changed in the file /etc/default/login.

This discussion about the various ways of changing ULIMT has been
interesting, but no one has asked what I think is the most interesting
question - why on earth is there a 12288 block limit in
/etc/conf/cf.d/mtune anyway? Suppose I want to create a file greater
than 6 megs? Why should the kernel care? Heck, the source for X11R3,
tar'ed and compressed is 8 megs long, and even root can't bring it over
and do anything with it. 

Is there some silly limit in the kernel, or can we change mtune and do
some real work? I guess I'll try on Monday, and find out. (Can't reboot
it from home ;-). 

-- 
Dave Remien - WINCO Computer Eng. Group -{uunet | bigtex}!pmafire!dave- 
"I'm looking for the same old place.  You must mean the old same place. 
It's right out back, sonny, here's the key." (Firesign Theater, ca. 1970)