Credential descriptors

Joris Giovannangeli joris at giovannangeli.fr
Tue Jul 30 01:40:57 PDT 2013


Hi,

I was a bit bored of auditing kernel code to find which rights add to be
granted to filedescriptors lookup in various places, so i tried
something new.

Currently, a process which wants to change its real uid/gid have to be
privileges. That's why su is setuid for instance. And shared object are
used to change the authentification method, the session managment etc.
The openPAM library fills this goal on dragonFly.

I decided to try solving this differently. I've added a new type of
descriptors referencing an ucred structure [1]. The set of ucred
structures owned by a process is the set of credentials the process has
the right to setuid/setgid/setgroups. Hence, a process can grant
crendential to another by passing a filedescriptor trough a unix domain
socket.

A cred structure descriptor is created by a new syscall, opencred(),
which returns a descriptor to the credentials of the calling process.
Read operation returns the xucred structure associated to the ucred
structure of the filedescriptor. Write operation modify the ucred
structure using the passed xucred structure if the process is allowed to
do so. The write call implements the same policy as
setuid/setgid/setgroups.

The syscalls setuidfromfd/setgidfromfd/setgroupsfromfd change the
credentials (not only effectives ids, but real ids too) using the
credentials pointed to in the file descriptor.

As for userspace, i'm experimenting with su. The goal is to have su
connect to a unix domain socket, make a request, and receive a
filedescriptor it can use to setuid. I think a pam_proxy lib could
handle requests to a pam daemon.

One issue of this design is the use of pam polices. Policies are per
service authentication process, which are configured in /etc/pam.d/.
In pam, the calling process tells himself the policy it wants to the pam
library. In this design, it's ok since the calling process runs as
uid=0, and is considered trusted. In the daemon design, any process
could connect to the unix domain socket and should not be trusted. I
think it can be worked around by using a wheel like specific group and
evry process allowed to make request to the pam daemon could be setgid
to this group, the sockets would then be owned by root and this group.

I'm not even sure this model is working, i've only done some experiment
with a modified su yet, and it's not clear if this work is worth the
features it brings. Because the only point of this stuff is to drop
uid=0 from some processes like su/login, etc and put them in a daemon
which can be easily converted to capsicum sandboxing. The other side
effect is that theses tools can use pam policy whitout shared object and
can be statically linked.


Thanks for reading,

Joris

[1]
https://github.com/jorisgio/DragonFlyBSD/commit/c1c2b7c26c45c260aee50da0662ae0812bf4bcb4




More information about the Kernel mailing list