paul@devon.UUCP (Paul Sutcliffe Jr.) (01/08/87)
With all the talk about ulimit lately, I've decided to share my "cure" for the problem. This program (aptly called ``ulimit'') will run a command with any given file size limit. Since it runs as setuid root, ulimit is allowed to raise the maximum file size. But fear not, ulimit sets the process' user id back to that of the caller before forking the command, so a security hole is not created. For complete instructions, see the man page. The included makefile may require a few small changes. Remove the "-Dvoid=int" if your compiler supports the void type. Set DESTDIR to the directory you wish ulimit to reside in before typing "make install". You must be the super-user to do the install. This code has been compiled and run on IBM XENIX 1.0 and 2.0, SCO XENIX V/286, Tandy XENIX 3.0, and UNIX SysVR2 on Sperry 5000's. I have no idea if it will work (or is needed, for that matter) on BSD Unix. Save the part between the two "tear here" lines an run the resulting file through the Bourne shell. (e.g. sh ulimit.shar). Comments welcome! -paul ----------------------------- tear here ------------------------------- # To unbundle, sh this file echo x - Makefile 1>&2 cat >Makefile <<'End of Makefile' # Makefile for 'ulimit' # Copyright (C) 1987 by Paul Sutcliffe, Jr. (devon!paul) CC = cc -Dvoid=int NROFF = nroff CFLAGS = -s -O DESTDIR = /usr/local/bin ROOTUSR = root ulimit: ulimit.c $(CC) $(CFLAGS) -o ulimit ulimit.c install: ulimit cp ulimit $(DESTDIR) chown $(ROOTUSR) $(DESTDIR)/ulimit chgrp bin $(DESTDIR)/ulimit chmod 4711 $(DESTDIR)/ulimit man: ulimit.1 $(NROFF) -man ulimit.1 clean: rm -f ulimit.o core clobber: clean rm -f ulimit End of Makefile echo x - ulimit.1 1>&2 cat >ulimit.1 <<'End of ulimit.1' .tr ~ .TH ULIMIT 1 local .SH NAME ulimit~- get/set file size limit .SH SYNTAX .BR ulimit .RI [~newlimit~command~[~args~...~]~] .SH DESCRIPTION .I Ulimit with no arguments will display the current maximum file size for the calling process (usually the shell). .I Ulimit with at least two arguments will set the maximum file size to \fInewlimit\fR and then execute the \fIcommand\fR. The \fInewlimit\fR is specified in units of blocks (i.e. 512 bytes). Any additional arguments (if found) are passed through to the \fIcommand\fR. .SH EXAMPLE ulimit 4096 cat file1 file2 >largefile .PP This will allow \fIlargefile\fR to be 2 Megabytes. .SH SEE~ALSO sh(1), ulimit(2) .SH NOTES The name conflicts with the Bourne shell builtin \fIulimit\fR. .SH AUTHOR Paul Sutcliffe, Jr. (...!seismo!cbmvax!devon!paul) End of ulimit.1 echo x - ulimit.c 1>&2 cat >ulimit.c <<'End of ulimit.c' /* * ulimit.c - get/set user filesize limits * * Copyright (C) 1987 by Paul Sutcliffe, Jr. (devon!paul) * * Permission is hereby granted to copy, reproduce, redistribute or * otherwise use this software as long as: there is no monetary * profit gained specifically from the use or reproduction or this * software, it is not sold, rented, traded or otherwise marketed, and * this copyright notice is included prominently in any copy made. */ #ifndef lint static char *sccsid = "@(#)ulimit.c 2.1 (devon) 1/7/86"; #endif #include <sys/ulimit.h> extern int getuid(); extern long ulimit(); main(argc, argv) int argc; char *argv[]; { char *myname, *file; long curlimit, newlimit; myname = argv[0]; /* program name */ if (argc == 1) { /* show current ulimit */ if ((curlimit = ulimit(UL_GFILLIM, (long) 0)) < 0) { perror(myname); exit(1); } (void) printf("%ld\n", curlimit); } else if (argc >= 3) { /* set new ulimit and run command */ newlimit = atol((++argv)[0]); if (ulimit(UL_SFILLIM, newlimit) < 0) { perror(myname); exit(1); } (void) setuid(getuid()); /* run as real user, not root! */ file = (++argv)[0]; execvp(file, argv); perror(myname); /* in case execvp fails */ exit(1); } else exit(2); } End of ulimit.c ----------------------------- tear here ------------------------------- -- Paul Sutcliffe, Jr. UUCP: {seismo,ihnp4,allegra,rutgers}!cbmvax!devon!paul Devon Computer Services COMPUSERVE: 76176,502 Allentown, Penna. Sarek: "Any message for your mother, Spock?" +1 215 398 3776 Spock: "Yes. Tell her 'I feel fine.'"