[fpc-pascal] How to detect if my program is running with root/elevated privileges?

Mark Morgan Lloyd markMLl.fpc-pascal at telemetry.co.uk
Tue Oct 29 08:02:32 CET 2013


Bart wrote:
> On 10/28/13, Mark Morgan Lloyd <markMLl.fpc-pascal at telemetry.co.uk> wrote:
> 
>>>> For windows there is winutils.iswindowsadmin(), for unix likes there is
>>>> fpgeteuid (which should return zero for root).
>> Also remember unix-style capabilities.
>>
> 
> Care to elaborate on that?

You can use the setcap utility to add or remove capabilities to a 
binary. I can't remember how they're stored, or why this is considered 
even adequately secure. The capabilities library (e.g. libcap.so, don't 
confuse this with a file from Mozilla of the same name) can be used by a 
program to add capabilities to itself, provided that it starts off as 
uid root. Note that gtk2 does not allow a program to be setuid root.

Below cut-and-pasted from my notes from when I was last looking at this, 
sorry about the poor format. I've translated the appropriate header file 
and hacked together a shim for the .so, usual cautions about making sure 
it actually exists.

(* This requires that the program be running with sufficient 
capabilities to be *)
(* able to bind to ports < 1024, however immediately after this is done 
it goes *)
(* to a lot of trouble to relinquish as many privileges as possible. 
         *)
(* 
         *)
(*  *   If linked with gtk2, it is not possible to run setuid root but 
explicit *)
(*      capabilities may be added during installation: 
         *)
(* 
         *)
(*              # setcap CAP_NET_BIND_SERVICE=p+e *gtk2 
         *)

Final parameter is the name of the program just compiled, which in my 
case has widget set etc. appended.

(* 
         *)
(*      Note that capabilities are stored as extended attributes, which 
DO NOT  *)
(*      normally accompany a file if it is subsequently copied. 
         *)
(* 
         *)
(*  *   If linked with Qt, the program may be run setuid root: 
         *)
(* 
         *)
(*              # chown root:root *qt 
         *)
(*              # chmod u+s *qt 
         *)
(*              # chmod g+s *qt 
         *)
(* 
         *)
(*      or have extra capabilities as above. 
         *)
(* 
         *)
(*  *   In any case, the program may be started by the superuser (i.e. 
run as   *)
(*      root). 
         *)

..in which case it does the usual unix thing of grabbing whatever 
resources it needs, then switching to a safer UID so that if somebody 
finds a way of forcing it to shell out it doesn't give them unrestricted 
access to the system.

(* 
         *)
(* After the ports have been bound, the CAP_NET_BIND_SERVICE effective 
and      *)
(* permitted capabilities are relinquished. If the program is running 
setuid    *)
(* root, then it reverts to the actual user; if it is running as root it 
        *)
(* assumes group and user IDs as given in the configuration file, or as 
given   *)
(* by the ownership of the executable, or ID 65534 as ultimate fallback 
         *)
(* ("nobody" in recent Debian releases).                        MarkMLl. 
        *)

-- 
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]



More information about the fpc-pascal mailing list