lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 18 Mar 2020 12:56:37 +0100
From:   Christian Brauner <christian.brauner@...ntu.com>
To:     Simon Ser <contact@...rsion.fr>
Cc:     "ebiederm@...ssion.com" <ebiederm@...ssion.com>,
        Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
        "oleg\\@redhat.com" <oleg@...hat.com>,
        "christian\\@brauner.io" <christian@...uner.io>
Subject: Re: SO_PEERCRED and pidfd

On Wed, Mar 18, 2020 at 10:31:00AM +0000, Simon Ser wrote:
> On Tuesday, March 17, 2020 7:58 PM, <ebiederm@...ssion.com> wrote:
> 
> > Simon Ser contact@...rsion.fr writes:
> >
> > > Hi all,
> > > I'm a Wayland developer and I've been working on protocol security,
> > > which involves identifying the process on the other end of a Unix
> > > socket 1. This is already done by e.g. D-Bus via the PID, however
> > > this is racy 2.
> > > Getting the PID is done via SO_PEERCRED. Would there be interest in
> > > adding a way to get a pidfd out of a Unix socket to fix the race?
> >
> > I think we are passing a struct pid through the socket metadata.
> > So it should be technically feasible.
> >
> > However it does come with some long term mainteance costs.
> >
> > The big question is what is a pid being used for when being passed.
> > Last I looked most of the justifications for using metadata like that
> > with unix domain sockets led to patterns of trust that were also
> > exploitable.
> >
> > Looking at the proposale in 1 even if you have race free access
> > to /proc/<pid>/exe using pidfds it is possible to change /proc/<pid>/exe
> > to be anything you can map so that seems to be an example of a problem.
> 
> /proc/<pid>/exe is a symlink. It doesn't seem like it's possible to
> unlink it and re-link it to something else (fails with EPERM).
> 
> Is there a way to do this?

Not while the process is running afaik. Given the right permission there
are some tricks you can do to overwrite the host binary and trick
someone into rexecuting itself and thus the ovewritten binary (There's
been an exploit in runC around this which Aleksa and I fixed a while
back.) but as long as the process is running you can't overwrite it
(unless there are bugs).

> 
> > So it would be very nice to see a use case spelled out where
> > the pid reuse race mattered, and that trusting a pid makes sense.
> 
> The use-case is identifying which process is at the other end of the
> socket. Once the process is identified, security rules can be applied.
> For instance a Wayland compositor might give access to a
> screen capture interface if the program is a trusted screen shooter.
> 
> Some want to get the full path to the executable, and read the
> /proc/<pid>/exe symlink. Some want to read a special file created at
> the root of the process' file system namespace, and access
> /proc/<pid>/root.

You can translate solely from a pidfd to a pid and then open /proc/<pid>
and verify that the directory you just opened referes to the same
process as the pidfd. That's illustrated in a sample program I wrote.
It's located in the kernel sources at:

samples/pidfd/pidfd_metadata.c

specifically the pidfd_metadata_fd() helper.

If you only have the pidfd and want to know the pid of the process you
can translate from the fd's fdinfo file to the pid. That's e.g. how
systemd is doing it too. See
https://github.com/systemd/systemd/blob/06ae8800d0bd9f8b01df7443daec37f90708bd84/src/basic/process-util.c#L1499
If the process has already exited _and_ been reaped fdinfo will show -1
as pid. The format of the fdinfo file matches the output for the Pid:
and NSpid: fields in the /prop/<pid>/status file.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ