Verified auth tty ioctl()s implementation details

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Verified auth tty ioctl()s implementation details

multiplex'd
Hi all,

In the last couple of days I've been studying sudo(8) and doas(1) to
find out how they work and what their operational differences are.
With regards to storing persistent cookies, to allow a user to execute
further commands without reauthentication (subject to a timeout), sudo
uses a timestamp file and doas uses verified auth ioctls on the
controlling tty.

However, sudo and doas differ in the information stored in the persistent
cookie. sudo records the ID of the foreground process group on the
controlling terminal while doas records the parent process ID, according
to the description of TIOCSETVERAUTH in tty(4).

From an end-user standpoint, this means that if a user has run a
priviledged command using sudo and then (within the timeout) runs a
script which itself calls sudo, then they will not be prompted to
enter a password as the script is running with the same foreground
process group on the controlling terminal as the first invocation.
However, in the same scenario, doas would prompt for a password
when it is invoked from within the script, as its parent process ID
is different when running under an interactive user shell from when
it's executed in a shell script. (This can also be observed when
building ports with SUDO=doas, as doas is invoked at various points
in the build process under different make (sub)processes, which
results in doas prompting for a password many times.)

Now, I am running on the assumption that these ioctl()s were
implemented as a kernel-side component of doas's "password timeout"
functionality as observed when using the "persist" configuration
keyword. From that, my question is whether there is any particular
reason for recording the parent process ID in particular as part of
the cookie stored by the persistent authentication ioctl() as opposed
to the process group ID of the calling process's session leader, as
with sudo.

Regards.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Verified auth tty ioctl()s implementation details

Ted Unangst-6
multiplex'd wrote:

> From an end-user standpoint, this means that if a user has run a
> priviledged command using sudo and then (within the timeout) runs a
> script which itself calls sudo, then they will not be prompted to
> enter a password as the script is running with the same foreground
> process group on the controlling terminal as the first invocation.
> However, in the same scenario, doas would prompt for a password
> when it is invoked from within the script, as its parent process ID
> is different when running under an interactive user shell from when
> it's executed in a shell script. (This can also be observed when
> building ports with SUDO=doas, as doas is invoked at various points
> in the build process under different make (sub)processes, which
> results in doas prompting for a password many times.)
>
> Now, I am running on the assumption that these ioctl()s were
> implemented as a kernel-side component of doas's "password timeout"
> functionality as observed when using the "persist" configuration
> keyword. From that, my question is whether there is any particular
> reason for recording the parent process ID in particular as part of
> the cookie stored by the persistent authentication ioctl() as opposed
> to the process group ID of the calling process's session leader, as
> with sudo.

Yes, the difference is intentional. For pretty much exactly the reason you
noticed, although perhaps with the opposite result. A successful
authentication is not meant to be inherited by any random program or script
you run. A) because vague security concerns, but also B) because I think it's
weird that a script maybe works if it runs fast enough, but fails if it takes
five minutes to get to doas. Like "make; doas make install" works on a fast
machine but fails unexectedly on a slower machine.

A more robust approach to this problem is to invert privilege. Start as root,
then drop to another user.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Verified auth tty ioctl()s implementation details

multiplex'd
On Mon, Jul 17, 2017 at 04:39:10PM -0400, Ted Unangst wrote:

> Yes, the difference is intentional. For pretty much exactly the reason you
> noticed, although perhaps with the opposite result. A successful
> authentication is not meant to be inherited by any random program or script
> you run. A) because vague security concerns, but also B) because I think it's
> weird that a script maybe works if it runs fast enough, but fails if it takes
> five minutes to get to doas. Like "make; doas make install" works on a fast
> machine but fails unexectedly on a slower machine.
>
> A more robust approach to this problem is to invert privilege. Start as root,
> then drop to another user.

Thank you for explaining; I suspected the reasoning was such. Speaking specifically
about ports, is there a way to start a port build as root and then drop priviledges
(in a similar manner to the base system's build infrastructure)? A quick glance
through bsd.port.mk(5) suggests that this isn't (yet) possible. (A possible workaround
is to run "make fetch" as a normal user, "make prepare" as root and "make build" as
normal user etc, however if there are dependencies which need to be built at the "make
prepare" stage then they are built as root.)

Regards

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Verified auth tty ioctl()s implementation details

Stuart Henderson
On 2017-07-18, multiplex'd <[hidden email]> wrote:
> Thank you for explaining; I suspected the reasoning was such. Speaking specifically
> about ports, is there a way to start a port build as root and then drop priviledges
> (in a similar manner to the base system's build infrastructure)? A quick glance
> through bsd.port.mk(5) suggests that this isn't (yet) possible. (A possible workaround
> is to run "make fetch" as a normal user, "make prepare" as root and "make build" as
> normal user etc, however if there are dependencies which need to be built at the "make
> prepare" stage then they are built as root.)

dpb(8) handles this automatically, but it's a pain when you're starting
work on a new port from scratch especially if you don't have a
particularly clean ports tree.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Verified auth tty ioctl()s implementation details

Theo de Raadt-2
> On 2017-07-18, multiplex'd <[hidden email]> wrote:
> > Thank you for explaining; I suspected the reasoning was such. Speaking specifically
> > about ports, is there a way to start a port build as root and then drop priviledges
> > (in a similar manner to the base system's build infrastructure)? A quick glance
> > through bsd.port.mk(5) suggests that this isn't (yet) possible. (A possible workaround
> > is to run "make fetch" as a normal user, "make prepare" as root and "make build" as
> > normal user etc, however if there are dependencies which need to be built at the "make
> > prepare" stage then they are built as root.)
>
> dpb(8) handles this automatically, but it's a pain when you're starting
> work on a new port from scratch especially if you don't have a
> particularly clean ports tree.

This ran into the same problem as base system builds:  it isn't terribly
difficult to build a de-escalation mechanism into a large infrastructure
from the top-down, but it is much harder to build it for the internal
elements.

cd /usr/src/bin/ls; make.  No de-escalation occurs.  But in some ways
that matches the development process, so that is OK.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Verified auth tty ioctl()s implementation details

Theo de Raadt-2
In reply to this post by Ted Unangst-6
> > Now, I am running on the assumption that these ioctl()s were
> > implemented as a kernel-side component of doas's "password timeout"
> > functionality as observed when using the "persist" configuration
> > keyword. From that, my question is whether there is any particular
> > reason for recording the parent process ID in particular as part of
> > the cookie stored by the persistent authentication ioctl() as opposed
> > to the process group ID of the calling process's session leader, as
> > with sudo.
>
> Yes, the difference is intentional. For pretty much exactly the reason you
> noticed, although perhaps with the opposite result. A successful
> authentication is not meant to be inherited by any random program or script
> you run. A) because vague security concerns, but also B) because I think it's
> weird that a script maybe works if it runs fast enough, but fails if it takes
> five minutes to get to doas. Like "make; doas make install" works on a fast
> machine but fails unexectedly on a slower machine.

i'd like to point out that doas+kernel semantics are intended to be
stronger than what sudo does.   And if some finds a way for the kernel
to become more strict (further tie-in to process groups maybe?) then
we could do that easily and gain the security, as long as there is no
further loss in functional use.




Loading...