guy@auspex.auspex.com (Guy Harris) (09/01/90)
>It seems, however, that Sun has again hacked together and included in >their OS something without taking security aspects into account. The >uid != euid check is not enough in current Unix systems; some programs >which are setuid set their euid to the uid to which they're suid under Err, well, if it's set-uid, when it starts up its euid already *is* the uid to which it's suid. I don't think that's what you meant to say.... >and so the linker happily links in the user's own library The libraries are mapped in before "main()" is called, so whether LD_LIBRARY_PATH is ignored depends only on the settings of the effective and real UID and GID at the time the program is initially started up, and is independent of what the program does after that. (Yes, I tried it.) >I tried to think of a few quick ways to exploit it and came up with only >/bin/login -p sync (preserver environment), if sync is an account with no >password and daemon id as a common convention is. OK, so the problem is something quite different from what you were saying it is. The problem isn't that "/bin/login "set(s) (its) euid to the uid to which it's suid", it's that, when invoked with the "-p" flag it passes LD_LIBRARY_PATH (and possibly other dangerous environment variables) through when it runs the login shell of an account with no password and that has a reasonably-privileged user ID. The fix ain't to change "ld.so"s rules for when it should honor LD_LIBRARY_PATH, it's to change "login" to be more selective about which environment variables it'll pass through.
jkp@cs.HUT.FI (Jyrki Kuoppala) (09/02/90)
In article <3991@auspex.auspex.com>, guy@auspex (Guy Harris) writes: >>It seems, however, that Sun has again hacked together and included in >>their OS something without taking security aspects into account. The >>uid != euid check is not enough in current Unix systems; some programs >>which are setuid set their euid to the uid to which they're suid under > >Err, well, if it's set-uid, when it starts up its euid already *is* the >uid to which it's suid. I don't think that's what you meant to say.... Oops, sorry, of course I meant to say that some programs set their real uid to the euid (the uid to which they're suid under), and this is the problem. >>and so the linker happily links in the user's own library > >The libraries are mapped in before "main()" is called, so whether >LD_LIBRARY_PATH is ignored depends only on the settings of the effective >and real UID and GID at the time the program is initially started up, >and is independent of what the program does after that. (Yes, I tried >it.) Yes, but some programs start _other_ programs after setting uid to euid; in this case, euid == uid and when this other program (like when /bin/login starts the login shell /bin/sync) is loaded the LD_LIBRARY_PATH is used. This is the problem, sorry if I was a bit unclear. >>I tried to think of a few quick ways to exploit it and came up with only >>/bin/login -p sync (preserver environment), if sync is an account with no >>password and daemon id as a common convention is. > >OK, so the problem is something quite different from what you were >saying it is. The problem isn't that "/bin/login "set(s) (its) euid to >the uid to which it's suid", it's that, when invoked with the "-p" flag >it passes LD_LIBRARY_PATH (and possibly other dangerous environment >variables) through when it runs the login shell of an account with no >password and that has a reasonably-privileged user ID. The fix ain't to >change "ld.so"s rules for when it should honor LD_LIBRARY_PATH, it's to >change "login" to be more selective about which environment variables >it'll pass through. Yes; and change all those dozen's of other programs (like the ones which come from the Usenet) to also unsetenv LD_LIBRARY_PATH when they do setuid(geteuid()). No, I don't really know if this is common but it's hard to know exactly what programs do this (especially for SunOS binary users) and so the problem is hard to solve this way. And I haven't figured out a good way to change LD_LIBRARY_PATH semantics. Perhaps a kludge to the setuid() function which unsetenv's LD_LIBRARY_PATH when euid != uid and setuid() is used to set it to the real uid ? This would solve the problem in the general case, you would just have to recompile (umm, with shared libraries you wouldn't have to recompile, something useful about them too ;-) However, the security aspects of LD_LIBRARY_PATH should be documented (well, I don't know if they are, I haven't read all the SunOS manuals). So, anyone see somthing wrong with the solution: We write a kludged setuid() to unsetenv LD_LIBRARY_PATH and distribute it with instructions of how to install it in your machine's shared library. We also find out which staticcally-linked programs have the problem and instruct users to recompile them and distribute fixed binaries for binary-only users. //Jyrki [ I vote for creation of a newsgroup called comp.unix.wizards ]
guy@auspex.auspex.com (Guy Harris) (09/03/90)
>Rather, it's to make login non-setuid in the first place. The only time >login should run as root is from a controlled daemon, such as telnetd or >getty. I've no problem with that; others used to doing "login" from their sessions might, but, well, you know what happens if you can't take a joke.... However, "login" ain't the only program that will pass environment variables through when it runs some program under another user ID (real *and* effective *and* saved set-user), so making "login" non-set-UID doesn't completely close the hole....
gt0178a@prism.gatech.EDU (BURNS,JIM) (09/03/90)
in article <4006@auspex.auspex.com>, guy@auspex.auspex.com (Guy Harris) says: >>Rather, it's to make login non-setuid in the first place. The only time >>login should run as root is from a controlled daemon, such as telnetd or >>getty. > I've no problem with that Excuse me, but I don't understand how login (su, rsh, rlogin) would be able to change your uid without using setuid(3) which is documented as needing superuser status: NAME setuid, seteuid, setruid, setgid, setegid, setrgid - set user and group ID [...] These calls are only permitted to the super-user or if the argument is the real or effective ID. -- BURNS,JIM Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332 uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a Internet: gt0178a@prism.gatech.edu
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/03/90)
In article <13283@hydra.gatech.EDU> gt0178a@prism.gatech.EDU (BURNS,JIM) writes: > in article <4006@auspex.auspex.com>, guy@auspex.auspex.com (Guy Harris) says: > >>Rather, it's to make login non-setuid in the first place. The only time > >>login should run as root is from a controlled daemon, such as telnetd or > >>getty. > > I've no problem with that > Excuse me, but I don't understand how login (su, rsh, rlogin) would be > able to change your uid without using setuid(3) which is documented as > needing superuser status: It can't. All it can do without privileges is log you in as yourself again, and not even that on some systems. As I said in the triple-quoted comments, login should only run as root if it's run from a controlled (root) daemon: this is necessary for security. ---Dan
guy@auspex.auspex.com (Guy Harris) (09/04/90)
>> Excuse me, but I don't understand how login (su, rsh, rlogin) would be >> able to change your uid without using setuid(3) which is documented as >> needing superuser status: > >It can't. All it can do without privileges is log you in as yourself >again, and not even that on some systems. As I said in the triple-quoted >comments, login should only run as root if it's run from a controlled >(root) daemon: this is necessary for security. Yup, and as for the other commands: 1) "rsh" and "rlogin" use super-user privileges to get "privileged" ports, not to change your uid; "rshd" and "rlogind", the daemons, are the ones that change the UID, and they're not set-UID; 2) "su", however, *does* need to be setuid in order to be useful, but also passes environment variables through....
djw@bbn.com (David Waitzman) (09/04/90)
guy@auspex.auspex.com (Guy Harris) writes: } 1) "rsh" and "rlogin" use super-user privileges to get "privileged" } ports, not to change your uid; "rshd" and "rlogind"... I occasionally write and distribute programs that need to use raw IP sockets, roughly the same thing, protection-wise, as a program using "privileged" ports. I dislike needing to run the programs set-uid root (or by root) just to do this one special privileged thing. How do you all feel about the practice of using a special group that allows one to access privileged ports or raw IP sockets? The programs can then just be run setgid to that group. The kernel socket opening code would then allow the opening of privileged or raw sockets to either user==root or groups includes "priv_socket_group". Would vendors support this? We don't have access to Sun kernel source code anymore here. I understand that some people may have objections to the piece-meal addition of finer-granularity access rights to Unix. thanks, -david
gt0178a@prism.gatech.EDU (BURNS,JIM) (09/05/90)
in article <59263@bbn.BBN.COM>, djw@bbn.com (David Waitzman) says: > I understand that some people may have objections to the piece-meal > addition of finer-granularity access rights to Unix. SysV (or alt least HP-UX 7.0) already supports this with CHMOD, MLOCK, RTPRIO, etc., so those that use this scheme and also support sockets could add this easily. -- BURNS,JIM Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332 uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a Internet: gt0178a@prism.gatech.edu
jik@athena.mit.edu (Jonathan I. Kamens) (09/05/90)
In article <13340@hydra.gatech.EDU>, gt0178a@prism.gatech.EDU (BURNS,JIM) writes: |> Thanx, but I'm still a little confused - somehow, when you login to the |> remote host, it has to set your uid. If rshd and rlogind don't use |> setuid(3) (can't, if they aren't set-uid) to set your privileges, what |> does? They don't have to be setuid to use setuid(3). They have to run as root. If they are run by inetd, for example, they can be run as root even if they are not setuid root, since inetd runs as root. -- Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8495 Home: 617-782-0710
gt0178a@prism.gatech.EDU (BURNS,JIM) (09/05/90)
in article <1990Sep4.235353.18586@athena.mit.edu>, jik@athena.mit.edu (Jonathan I. Kamens) says: > They don't have to be setuid to use setuid(3). They have to run as root. > > If they are run by inetd, for example, they can be run as root even if they > are not setuid root, since inetd runs as root. Thanx. -- BURNS,JIM Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332 uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a Internet: gt0178a@prism.gatech.edu
gla@nixpbe.UUCP (R. Glaschick) (09/05/90)
In <59263@bbn.BBN.COM> djw@bbn.com (David Waitzman) writes: >I occasionally write and distribute programs that need to use raw IP >sockets, roughly the same thing, protection-wise, as a program using >"privileged" ports. I dislike needing to run the programs set-uid root >(or by root) just to do this one special privileged thing. I fully agree. See e.g. mail, that does not have super user rights. >How do you all feel about the practice of using a special group that >allows one to access privileged ports or raw IP sockets? The programs >can then just be run setgid to that group. The kernel socket opening >code would then allow the opening of privileged or raw sockets to >either user==root or groups includes "priv_socket_group". This is the right way to do it. But beware of the subtelties of the setuid() function. It works different under root and a normal user-id. ? Does someone have a precise description how to use setuid() ? >Would vendors support this? We don't have access to Sun kernel source >code anymore here. Vendor support does not depend wheather you have the source code. If you stick to e.g. X/OPEN, you will have vendor support. The X/OPEN XPG 3 specification is the same as in System V.3, but not complete and partially misleading. >I understand that some people may have objections to the piece-meal >addition of finer-granularity access rights to Unix. I think that this is correct usage of the existing security features, and nothing else. All those people using root whenever they need privileges without considering 'least privileges' are misusing the system. -- Rainer Glaschick, NIXDORF Computer AG, Paderborn, W-Germany EMail: glaschick.pad@nixdorf.com (US) or glaschick.pad@nixdorf.de (EU) Tel. +49 5251 14 6150 (office) +49 5254 6238 (home) Fax: +49 5251 14 6569
gt0178a@prism.gatech.EDU (BURNS,JIM) (09/11/90)
in article <1990Sep2.093254.11284@santra.uucp>, jkp@cs.HUT.FI (Jyrki Kuoppala) says: > So, anyone see somthing wrong with the solution: We write a kludged > setuid() to unsetenv LD_LIBRARY_PATH and distribute it with > instructions of how to install it in your machine's shared library. > We also find out which staticcally-linked programs have the problem > and instruct users to recompile them and distribute fixed binaries for > binary-only users. If I've followed this correctly, the problem is not that 'login' sets uid= euid, since 'login' is set-uid to root (which has been complained about previously in this thread) and login certainly isn't setting uid=root. It's setting uid= to the uid field of the record in /etc/passwd that you supplied the correct account & password for. Of course, 'login -p' could still pass a Trojan Horse library in to a relatively more privileged account that you DO know the password for (as opposed to your suggestion that the privileged account has no password - a definite no-no in the first place.) (I would imagine that 'su' w/o the '-' would work the same way.) Presumably then 'login' has to set uid=setuid(found uid), and THEN set euid=seteuid(uid). The reverse order wouldn't work, since if euid was no longer root, then setuid() would fail. Your suggestion then that, since euid=root!=uid before the setuid(), setuid() should unset LD_LIBRARY_PATH would appear to work. However, getting all those users to recompile or download their binaries is a bit of a problem. How many machines at your site don't even run the latest version of the OS, let alone have the latest patches? And who's going to determine which of those "statically-linked programs" needs to be re-compiled? The vendor? In what year? -- BURNS,JIM Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332 uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a Internet: gt0178a@prism.gatech.edu
lyndon@cs.athabascau.ca (Lyndon Nerenberg) (09/12/90)
jkp@cs.HUT.FI (Jyrki Kuoppala) writes: >So, anyone see somthing wrong with the solution: We write a kludged >setuid() to unsetenv LD_LIBRARY_PATH and distribute it with >instructions of how to install it in your machine's shared library. >We also find out which staticcally-linked programs have the problem >and instruct users to recompile them and distribute fixed binaries for >binary-only users. Yes. A kludge is a kludge, and should be avoided at all costs. What we really need is an option to ldconfig that allows the system administrator to specify path components in LD_LIBRARY_PATH that will be honoured by setuid programs. Or perhaps the option should just hardwire a value for LD_LIBRARY_PATH that's used by setuid programs. The latter isn't quite as nice a solution, though (IMHO). Something like: ldconfig [ directory ... ] [ [ -T directory ] ... ] where the -T flag is used to specify directories that are "trusted" in the sense that they would be searched by ld when running a setuid program. -- Lyndon Nerenberg VE6BBM / Computing Services / Athabasca University {alberta,cbmvax,mips}!atha!lyndon || lyndon@cs.athabascau.ca The only thing open about OSF is their mouth. --Chuck Musciano
guy@auspex.auspex.com (Guy Harris) (09/13/90)
>Yes. A kludge is a kludge, and should be avoided at all costs. What we >really need is an option to ldconfig that allows the system administrator >to specify path components in LD_LIBRARY_PATH that will be honoured by >setuid programs. Yes, some mechanism such as that - which might *also* want to, e.g., allow the system administrator to specify path components in boring old PATH that set-UID programs can trust - might be nice. It would, however, *NOT* affect the problem Jyrki is discussing! The problem there isn't with setUID programs, it's with programs that 1) let you run e.g. some user's login shell, under their UID, even if that user's account has no password (in which case it won't ask you for a password), and 2) pass LD_LIBRARY_PATH (or any of various other environment variables, although the others can generally be reamed out of the environment very early on in "main()", while LD_LIBRARY_PATH is used before "main()" is even called) through unmolested when running said login shells.