I've tried to set up the stanard wrapper for our systems
which does following:
- verifies if scipt's file system allowed to run setuid
scrits
- clears all environment variables, or pass only desired,
or set to values from hash-line in the script
- closes all file descriptros > 2 if -c options is set
- checks if script file is write permission for anyone
http://suidscript.sply.org/suidscript/suidscript.c
http://suidscript.sply.org/suidscript/suidscriptperl
http://suidscript.sply.org/suidscript/test_perl
http://suidscript.sply.org/
Is it strong enough? Maybe there is any slippery ground
left?
_______________________________________________
freebsd...@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hacke...@freebsd.org"
The biggest problem is a race condition between the kernel setting up
the set[gu]id() environment and opening the script to find the
interpreter and the interpreter opening the script to execute it.
This can only be fixed withing the kernel (by passing the script to
the interpreter as a pre-opened FD).
>Is it strong enough? Maybe there is any slippery ground
>left?
The biggest problem is its failure to check the sanity of the input
parameters - that a particular argument actually exists before
referencing it.
Other issues I noticed:
- strncpy() is virtually always the wrong function. You already do
validation so you could just use strcpy()
- strncpy(penvd + penvsz, "=", 1); could be penvd[penvsz] = '=';
- No error if number of environment variables too great.
--
Peter Jeremy
Do you mean that evil Bob can substitue Alice's script between stat() and execve() calls?
Yes, I've missed this point.
We can use realpath and check if all nodes are writable only by file owner or by root.
Yes, that's a big limitation, but in most common tasks it would be acceptable. And it
saves from race conditions, am I right?
And there are another ways but more slowly or complex - own sub-wrapper for each
interpreter with passes script as file descriptor as you wrote at beginning; hardlink or
copy files to safe directory; fork child and ptrace him for watching if the files it
opens are really the same. Too confusing.
But if the first way is ok, maybe it'sbetter to stay on it.
> Other issues I noticed:
> - strncpy() is virtually always the wrong function. You already do
> validation so you could just use strcpy()
ok. i've replace to memcpy as len is already known
> - strncpy(penvd + penvsz, "=", 1); could be penvd[penvsz] = '=';
sure, it was done only for hold in one style all string operations
> - No error if number of environment variables too great.
fixed
Actually Bob can replace the script anytime between the initial statfs() call
in your script and the interpreter opening the script sometime after the
execve() call. You should be able to get around this by opening the script
first, using fstatfs() and fstat() and passing the script as /dev/fd/N to
the interpreter.
What I was actually referring to was your use of argv[1], argv[2], argv[3]
and argv[4] without checking argc or otherwise validating them.
--
Peter Jeremy
Great idea. Thank you very much.
> What I was actually referring to was your use of argv[1], argv[2], argv[3]
> and argv[4] without checking argc or otherwise validating them.
Oops, I did it.
Current implementation checks the safety of an interpreter path and of a script path - all nodes required to be owned by root or script owner and writable only by owner. It's a big limitation, but it works in most cases.
I've tried /dev/fd/ way, but it requires fdescfs mounted which is not common for different freebsd versions and sometimes seems a little buggy. I've included suidscript_fdesc.c which implements /dev/fd/*, but I haven't evere tested it because mount_fdescfs crashes.