Date: Tue, 22 Jul 2003 13:14:39 -0600 (CST) From: Ryan Thompson <ryan@sasknow.com> To: "Gerald S. Stoller" <gs_stoller@hotmail.com> Cc: FreeBSD Questions <freebsd-questions@freebsd.org> Subject: Re: set user-id Message-ID: <20030722123627.A21583-100000@ren.sasknow.com> In-Reply-To: <Sea1-F1124yp8ARf3sl0001b188@hotmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[ Please CC questions@FreeBSD.org (or "Reply to All") when replying ] Gerald S. Stoller wrote to ryan@sasknow.com: > >Please give complete examples. As posted, your example wouldn't run > >without invoking sh(1) first. I'm assuming it was something like: > > > > #!/bin/sh > > echo $USER | tee xx > > You're right, sorry, I had '#!/bin/ksh' as the first line. Yep. Interpreted script. > > > How do I get set user-id to work? > > > Your permissions are fine, but you're hitting a more subtle problem: > > S*id bits don't work for interpreted scripts (denoted by the > > shebang, #!), by design. If you'd compiled the equivalent example to > > a binary, I'd expect it to work as you intended. > Now that you mention it, I recall finding this condition on HP-UX > (Hewlett-Packard Unix) where I got around it by making a small > compiled program that invoked the script. Well, why don't you just chmod 4755 /bin/ksh, then. :-D > Anyway, it should be in the man pages of chmod and maybe someplace > else. Since it is so easy to get around, why bother with this > restriction? Presume that the person who wrote the script knows what > he is doing and don't put in special cases!!! The main reason is you don't actually "execute" a script. If you type in /path/to/script, the OS first ensures that you have execute permission. If so, it checks the magic number of the file (first two bytes), which determine the executable type. If the magic number is a "shebang" (#!), execve(2) actually execve's the interpreter, with your script as an argument. Suppose you have a script executed with "./foo" with #!/bin/ksh as the interpreter. It'll be executed just as if you'd run /bin/ksh ./foo Now you can see why the s*id bits on scripts don't mean anything. It *would* be possible to alter this behaviour at the OS level, and, although I haven't looked in a while, it would probably be a relatively trivial change. That, combined with the fact that this is a FAQ, suggests that there are good reasons why this "feature" hasn't been adopted. (And FreeBSD isn't alone, either :-) Namely, if the shell script allows for any interactive escapes, the caller has an interactive root shell. Also, shell scripts are particularly vulnerable to PATH modifications, if not set explicitly in the script. There are other challenges, too. These are by no means impossible to work around, but there are almost always stronger solutions, in my opinion. Shells have a lot of hidden complexity, in order to allow you to make simple scripts. I can think of one time in the last eight or ten years that I've been tempted to make a setuid script. I came to my senses quickly. :-) If you *really* want to have suid scripts, your binary wrapper idea is quite a common trick. Don't get fancy with it, though. A one-liner to execve(2) should really be all you need. Either that, or re-code the whole thing in C (or some other compiled language). C can introduce insecurities of its own, but at least you'd (arguably) have put them there yourself. :-) - Ryan -- Ryan Thompson <ryan@sasknow.com> SaskNow Technologies - http://www.sasknow.com 901-1st Avenue North - Saskatoon, SK - S7K 1Y4 Tel: 306-664-3600 Fax: 306-244-7037 Saskatoon Toll-Free: 877-727-5669 (877-SASKNOW) North America
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030722123627.A21583-100000>