Best way to gain root privileges

Adam Skutt askutt at gmail.com
Thu Feb 17 13:39:56 EST 2011


On Feb 17, 10:32 am, GSO <gso... at yahoo.co.uk> wrote:
> > I'm having a awfully hard time figuring out why a home CCTV
> > application might need privilege at all.  Are you sure you really need
> > privilege?  It sounds to me like there may be some larger design
> > issues mandating the need for privilege when it's not really
> > necessary.
>
> A user login should only able to view the footage.  It's important
> that a user login cannot delete any images/video.  This much can be
> done with ACL - but having said that a user login would still be able
> to copy the images/video, so ACL would work but is not ideal - I could
> prevent copying with raised privileges.

No, you can't.  If I can read the data, I can copy the data.  How did
you think you were going to prevent copying?  Remember that copying is
just read()/write() in a loop.

> If I were to allow a user to
> archive footage without using an admin login then that would require
> ACL with write access, which is out of the question.
>
> If a camera loses its connection I think it's OK to let a user restart
> the camera without using gksu, but this would require raised
> privileges.
>
> There are other misc. points where I need write access.  The directory
> where images are stored by the live feed can become 'messy' (for want
> of a better way of putting it), write access is needed to tidy it up
> before live camera images can be viewed, it's not really appropriate
> to use gksu here every time a user wants to view the live images.
> Also (I don't know exactly how I'm going to do this yet) but I'm
> thinking I might use the system log functions (syslogd) as part of a
> scheme to ensure the integrity of saved footage and the archive.
>

As Terry suggests (and I fully concur), all of these issues are best
solved by having a privileged daemon (though it may not need to be
root or entirely root).

Inter-process communication, if necessary, can be handled by UNIX
domain sockets.  There are then a few ways to validate the privileges
of the users connecting to the sockets:

* UNIX sockets support passing credentials across the socket for
privilege checks.  This is however somewhat non-portable (different
platforms do it differently), and I'd imagine a minor PITA in the
Python.

* Create sockets with different ownership/permissions and then require
the users to be in the correct UNIX group.  Note that the permissions
of the sockets themselves are ignored on some platforms, so each
socket needs to be in a directory with the correct permissions and
ownership set:
/var/run/cctvd/admin/ <--- cctv:cctvadmin 750
/var/run/cctvd/admin/socket <--- Doesn't matter, so 777 cctv:cctvadmin
is fine
/var/run/cctvd/user/ <---- cctv:cctv 750 (or cctvuser for the group,
if you'd rather)
/var/run/cctvd/user/socket <--- Doesn't matter, so 777 cctv:cctv

Though these days it may be overkill, you may be able to rely on the
socket write permission (the others don't matter) and user/group for
protection.  You can also do actual authentication, but that's another
huge can of worms best left undisturbed if possible.

* It also allows you to simply stream the files over the sockets
instead of the client accessing the files directly.  Your call,
though.

Done properly, there's a high probability the only thing that needs to
run as root is the init script. You may also need startup code that
runs as root (not setuid root) that handles daemonization, opens
anything that must be open as root, and then drops root privileges.
Lots of daemons do this, so you can find examples out there on how to
accomplish this.  There are also utilities that can handle this for
you, which may be adequate in your situation.

Privilege separation can be used so that a bug in handling the user
socket doesn't accidentally grant someone admin and/or root privileges
(basically, have separate processes with separate privileges).  There
are examples out there of how to achieve this for various purposes as
well.

As a rule, when you find yourself needing privilege escalation, you
should go back and see if there is another way to achieve what you
want.  There's a good chance the other way will be a better way.

It sounds to me like you need to better define all the operations that
your software needs to be able to accomplish and what privileges are
necessary to accomplish each operation.  Once you've defined that, it
should become much easier to build a design that properly handles each
operation without the need for privilege escalation.

Adam



More information about the Python-list mailing list