[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: the watchdog of login program

From: Roland McGrath
Subject: Re: the watchdog of login program
Date: Mon, 30 Aug 2004 15:21:23 -0400 (EDT)

> You mean auth_makeauth inside ugids_verify_make_auth, right?


> Without being root, login makes ids of new user.

Oh, yeah.  I never really paid attention to the password server.

So login only needs to be setuid if you aren't using the password server,
in theory.  The things that are failing are proc_setowner and chown called
before the exec.  Those are using the old proc and auth state rather than
the state that is being passed to file_exec, so they don't have the benefit
of the auth handle from the password server.

login needs to make the proc_setowner call on the reauthenticated proc port
instead of the one it got from getproc.  I bet if you move that call down
and make it use ports[INIT_PORT_PROC] after the exec_reauth, it will work.

The other issue is the chown call on the tty.  This is just not going to
work on a vanilla tty node without having root.  Probably the thing to do
here is to have login use file_chown on the reauthenticated fds[0] port
(perhaps after checking it's a tty) rather than using `chown' per se as it
does now.  Then we would have change term to permit a nonroot nonowner
chown'ing the node e.g. if all live ctty protids' pid et al match his.

Looking at login makes me think that there is a security issue we should
fix, though.  Once you call proc_setowner, then anyone authenticated with
that owner uid (or anyone in your login collection if you now have no owner
uid) gets permission from the proc server to do anything to you.  So, it is
not safe to call proc_setowner if the process still has access to anything
that the user being logged in shouldn't.  When login is not setuid, this is
probably nothing at all, but I'm not positive.  When login is setuid, it
has lingering ports around authenticated as root.  

So I think login should be changed to drop all the old ports before calling
exec.  If you've already dropped the ref in PROC_SERVER, then there should
be nothing but libc state of init and fd ports.  The simplest thing is to
just do:

        close(0); close(1);

and then call proc_setowner, right before calling file_exec.  Btw,
file_exec will leak some send rights in the task, so it really ought to use
the EXEC_NEWTASK flag as well.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]