patch to indir (2.3 --> 2.4)
Maarten Litmaath
maart at nat.vu.nl
Wed Feb 20 10:49:17 AEST 1991
I've sent these diffs to comp.sources.unix, but as that group has been
rather quiet lately, posting them to alt.sources as well seems justified...
Included is a second minor patch to indir (from version 2.3 to 2.4).
Version 2.3 did not support multiple groups (see getgroups(2)).
The new version has this corrected. Thanks to John M. Sellens
<jmsellens at watdragon.uwaterloo.ca> (and Andy at the same site) for
pointing it out. He also mentioned that the Makefile and the test
script assumed the installer had `.' in his PATH. This has been
fixed too. Finally there are a few cosmetic changes to a few files.
To apply the patches below, in the directory containing the sources
of indir 2.3 unpack the shell archive and type:
patch < indir2.4diffs
Then check the file `README' and the Makefile. Type `make' to create
the new version of indir in the current directory.
Enjoy.
BTW, please note that my email address has changed.
Maarten Litmaath <maart at nat.vu.nl>
^^^
: This is a shar archive. Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin:/usr/ucb
echo Extracting 'indir2.4diffs'
sed 's/^X//' > 'indir2.4diffs' << '+ END-OF-FILE ''indir2.4diffs'
X*** old/Makefile Sat Feb 2 07:19:48 1991
X--- Makefile Sat Feb 2 07:23:38 1991
X***************
X*** 5,11 ****
X # a few defines for testing purposes; if you test in the current
X # directory the paths needn't be absolute
X # the path of indir will be used in #! lines -> max. 32 characters for
X! # #! + name + mandatory option
X PATH_OF_INDIR = ./indir
X TEST_DIRECTORY = .
X
X--- 5,11 ----
X # a few defines for testing purposes; if you test in the current
X # directory the paths needn't be absolute
X # the path of indir will be used in #! lines -> max. 32 characters for
X! # #! + name + space (or tab) + mandatory option
X PATH_OF_INDIR = ./indir
X TEST_DIRECTORY = .
X
X***************
X*** 21,32 ****
X $(CC) -O -o indir $(OBJS)
X
X exec_ok:
X! exec_test
X
X test: exec_ok
X test -f tests_made || PATH_OF_INDIR=$(PATH_OF_INDIR) \
X! TEST_DIRECTORY=$(TEST_DIRECTORY) make_tests
X! do_tests
X
X lint:
X lint $(SRCS)
X--- 21,32 ----
X $(CC) -O -o indir $(OBJS)
X
X exec_ok:
X! ./exec_test
X
X test: exec_ok
X test -f tests_made || PATH_OF_INDIR=$(PATH_OF_INDIR) \
X! TEST_DIRECTORY=$(TEST_DIRECTORY) ./make_tests
X! ./do_tests
X
X lint:
X lint $(SRCS)
X*** old/do_tests Sat Feb 2 07:18:58 1991
X--- do_tests Sat Feb 2 07:23:38 1991
X***************
X*** 1,15 ****
X #!/bin/sh
X for i in wrong.* ok.*
X do
X! echo '' >&2
X! echo "$ ls -l $i" >&2
X! ls -l $i >&2
X! echo "$ cat $i" >&2
X! cat $i >&2
X! echo $
X! echo -n "-- hit return to run $i: " >&2
X read x
X! $i file_argument
X! echo -n "-- hit return to continue: " >&2
X read x
X done
X--- 1,18 ----
X #!/bin/sh
X+
X for i in wrong.* ok.*
X do
X! echo ''
X! echo "$ ls -l $i"
X! ls -l $i
X! echo "$ cat $i"
X! cat $i
X! echo "$ "
X! echo -n "-- hit return to run $i: "
X read x
X! ./$i file_argument
X! echo -n "-- hit return to continue: "
X read x
X done
X+
X+ exit 0
X*** old/indir.c Sat Feb 2 07:19:48 1991
X--- indir.c Sat Feb 2 07:23:38 1991
X***************
X*** 1,4 ****
X! static char sccsid[] = "@(#)indir.c 2.3 90/03/31 Maarten Litmaath";
X
X /*
X * indir.c
X--- 1,5 ----
X! static char sccsid[] =
X! "@(#)indir.c 2.4 91/02/02 Maarten Litmaath @ CS, VU, Amsterdam";
X
X /*
X * indir.c
X***************
X*** 145,150 ****
X--- 146,152 ----
X execvp(Interpreter, Newargv);
X
X error(E_exec, Prog, Interpreter, File, geterr());
X+ /* NOTREACHED */
X }
X
X
X***************
X*** 270,276 ****
X char *f;
X {
X struct stat stbuf;
X! int xmask, pid;
X uid_t uid;
X gid_t gid;
X static int status = -1, checked = 0;
X--- 272,278 ----
X char *f;
X {
X struct stat stbuf;
X! int xmask, pid, groups_member();
X uid_t uid;
X gid_t gid;
X static int status = -1, checked = 0;
X***************
X*** 301,308 ****
X gid = Gid_check ? getgid() : getegid();
X
X xmask = (Uid == 0) ? (X_USR | X_GRP | X_OTH) :
X! st->st_uid == uid ? X_USR :
X! st->st_gid == gid ? X_GRP :
X X_OTH;
X /*
X * Can the invoker really execute the file we're reading from?
X--- 303,311 ----
X gid = Gid_check ? getgid() : getegid();
X
X xmask = (Uid == 0) ? (X_USR | X_GRP | X_OTH) :
X! (st->st_uid == uid) ? X_USR :
X! (st->st_gid == gid) ? X_GRP :
X! groups_member(st->st_gid) ? X_GRP :
X X_OTH;
X /*
X * Can the invoker really execute the file we're reading from?
X***************
X*** 330,335 ****
X--- 333,355 ----
X while (wait(&w) != pid)
X ;
X return ok(w) ? status = 0 : -1;
X+ }
X+
X+
X+ static int groups_member(gid)
X+ int gid;
X+ {
X+ register
X+ int *p, ngroups;
X+ int groups[NGROUPS];
X+
X+ if ((ngroups = getgroups(NGROUPS, groups)) < 0)
X+ return 0;
X+ p = groups;
X+ while (--ngroups >= 0)
X+ if (*p++ == gid)
X+ return 1;
X+ return 0;
X }
X
X
X*** old/setuid.txt Sat Feb 2 07:19:49 1991
X--- setuid.txt Sat Feb 2 07:23:38 1991
X***************
X*** 1,6 ****
X--- 1,7 ----
X Setuid Shell Scripts
X --------------------
X how to get them safe
X+ version 1.1
X
X Maarten Litmaath
X (maart at cs.vu.nl)
X***************
X*** 42,54 ****
X Yes, one needs write permission somewhere on the same device, if one's
X operating system doesn't support symbolic links.
X
X! What about the csh command interpreter? Well, 4.2BSD provides us with a csh
X! which has a NEW option: "-b"! Its goal is to avoid just the thing described
X! above: the mnemonic for `b' is `break'; this option prevents following
X! arguments of an exec of /bin/csh from being interpreted as options...
X! The csh refuses to run a setuid shell script unless the option is present...
X Scheme:
X! #!/bin/csh -b
X ...
X
X execl("-i", "unimportant", (char *) 0);
X--- 43,54 ----
X Yes, one needs write permission somewhere on the same device, if one's
X operating system doesn't support symbolic links.
X
X! What about the bare `-' option present in modern versions of the Bourne
X! shell? Its goal is to avoid just the thing described above: this option
X! prevents following arguments of an exec of /bin/sh from being interpreted
X! as options...
X Scheme:
X! #!/bin/sh -
X ...
X
X execl("-i", "unimportant", (char *) 0);
X***************
X*** 58,64 ****
X
X setuid(0);
X setgid(0);
X! execl("/bin/csh", "csh", "-b", "-i", (char *) 0);
X
X And indeed the contents of the file "-i" are executed!
X However, there's still another bug hidden, albeit not for long!
X--- 58,64 ----
X
X setuid(0);
X setgid(0);
X! execl("/bin/sh", "sh", "-", "-i", (char *) 0);
X
X And indeed the contents of the file "-i" are executed!
X However, there's still another bug hidden, albeit not for long!
X***************
X*** 82,95 ****
X currently the total length of shell + argument mustn't exceed 32 chars
X (easily fixed);
X 2)
X! 4.[23]BSD csh is expecting a `-b' flag as the first argument, instead
X! of the full path (easily fixed);
X 3)
X the interpreter gets an extra argument;
X 4)
X the difficulty of maintaining setuid shell scripts increases - if one
X moves a script, one shouldn't forget to edit it... - editing in turn
X! could turn off the setuid bits, so one shouldn't forget to chmod(1)
X the file `back'... - conceptually the solution above isn't `elegant'.
X
X How does indir(1) tackle the problems? The script to be executed will look
X--- 82,95 ----
X currently the total length of shell + argument mustn't exceed 32 chars
X (easily fixed);
X 2)
X! when executing a setuid script, 4.[23]BSD csh is expecting a `-b' flag
X! as the first argument, instead of the full path (easily fixed);
X 3)
X the interpreter gets an extra argument;
X 4)
X the difficulty of maintaining setuid shell scripts increases - if one
X moves a script, one shouldn't forget to edit it... - editing in turn
X! could turn off the setuid bit, so one shouldn't forget to chmod(1)
X the file `back'... - conceptually the solution above isn't `elegant'.
X
X How does indir(1) tackle the problems? The script to be executed will look
+ END-OF-FILE indir2.4diffs
chmod 'u=rw,g=r,o=r' 'indir2.4diffs'
set `wc -c 'indir2.4diffs'`
count=$1
case $count in
6805) :;;
*) echo 'Bad character count in ''indir2.4diffs' >&2
echo 'Count should be 6805' >&2
esac
exit 0
More information about the Alt.sources
mailing list