xref: /aosp_15_r20/external/libcap-ng/README.md (revision 8dd5e09d5faf27a871e8654ddaa2d2af7c696578)
1*8dd5e09dSSadaf Ebrahimilibcap-ng
2*8dd5e09dSSadaf Ebrahimi=========
3*8dd5e09dSSadaf Ebrahimi
4*8dd5e09dSSadaf EbrahimiThe libcap-ng library should make programming with POSIX capabilities
5*8dd5e09dSSadaf Ebrahimieasier. The library has some utilities to help you analyse a system
6*8dd5e09dSSadaf Ebrahimifor apps that may have too much privileges.
7*8dd5e09dSSadaf Ebrahimi
8*8dd5e09dSSadaf EbrahimiThe included utilities are designed to let admins and developers spot apps from various ways that may be running with too much privilege. For example, any investigation should start with network facing apps since they would be prime targets for intrusion. The netcap program will check all running apps that have listening socket and display the results. Sample output from netcap:
9*8dd5e09dSSadaf Ebrahimi
10*8dd5e09dSSadaf Ebrahimi```
11*8dd5e09dSSadaf Ebrahimippid  pid   acct       command          type port  capabilities
12*8dd5e09dSSadaf Ebrahimi1     2295  root       nasd             tcp  8000  full
13*8dd5e09dSSadaf Ebrahimi2323  2383  root       dnsmasq          tcp  53    net_admin, net_raw +
14*8dd5e09dSSadaf Ebrahimi1     2286  root       sshd             tcp  22    full
15*8dd5e09dSSadaf Ebrahimi1     2365  root       cupsd            tcp  631   full
16*8dd5e09dSSadaf Ebrahimi1     2286  root       sshd             tcp6 22    full
17*8dd5e09dSSadaf Ebrahimi1     2365  root       cupsd            tcp6 631   full
18*8dd5e09dSSadaf Ebrahimi2323  2383  root       dnsmasq          udp  53    net_admin, net_raw +
19*8dd5e09dSSadaf Ebrahimi2323  2383  root       dnsmasq          udp  67    net_admin, net_raw +
20*8dd5e09dSSadaf Ebrahimi1     2365  root       cupsd            udp  631   full
21*8dd5e09dSSadaf Ebrahimi```
22*8dd5e09dSSadaf EbrahimiAfter checking the networking apps, you should check all running apps with
23*8dd5e09dSSadaf Ebrahimipscap. If you are a developer and have to give your application
24*8dd5e09dSSadaf EbrahimiCAP_DAC_OVERRIDE, you must be accessing files for which you have no permission
25*8dd5e09dSSadaf Ebrahimito access. This typically can be resolved by having membership in the correct
26*8dd5e09dSSadaf Ebrahimigroups. Try to avoid needing CAP_DAC_OVERRIDE...you may as well be root if you
27*8dd5e09dSSadaf Ebrahimineed it.
28*8dd5e09dSSadaf Ebrahimi
29*8dd5e09dSSadaf EbrahimiSome application developers have chosen to use file system base capabilities
30*8dd5e09dSSadaf Ebrahimirather than be setuid root and have to drop capabilities. Libcap-ng provides
31*8dd5e09dSSadaf Ebrahimifilecap to recursively search directories and show you which ones have
32*8dd5e09dSSadaf Ebrahimicapabilities and exactly what those are.
33*8dd5e09dSSadaf Ebrahimi
34*8dd5e09dSSadaf EbrahimiC Examples
35*8dd5e09dSSadaf Ebrahimi----------
36*8dd5e09dSSadaf EbrahimiAs an application developer, there are probably 6 use cases that you are
37*8dd5e09dSSadaf Ebrahimiinterested in: drop all capabilities, keep one capability, keep several
38*8dd5e09dSSadaf Ebrahimicapabilities, check if you have any capabilities at all, check for certain
39*8dd5e09dSSadaf Ebrahimicapabilities, and retain capabilities across a uid change.
40*8dd5e09dSSadaf Ebrahimi
41*8dd5e09dSSadaf Ebrahimi1) Drop all capabilities
42*8dd5e09dSSadaf Ebrahimi   ```c
43*8dd5e09dSSadaf Ebrahimi   capng_clear(CAPNG_SELECT_BOTH);
44*8dd5e09dSSadaf Ebrahimi   capng_apply(CAPNG_SELECT_BOTH);
45*8dd5e09dSSadaf Ebrahimi   ```
46*8dd5e09dSSadaf Ebrahimi
47*8dd5e09dSSadaf Ebrahimi2) Keep one capability
48*8dd5e09dSSadaf Ebrahimi   ```c
49*8dd5e09dSSadaf Ebrahimi   capng_clear(CAPNG_SELECT_BOTH);
50*8dd5e09dSSadaf Ebrahimi   capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_CHOWN);
51*8dd5e09dSSadaf Ebrahimi   capng_apply(CAPNG_SELECT_BOTH);
52*8dd5e09dSSadaf Ebrahimi   ```
53*8dd5e09dSSadaf Ebrahimi
54*8dd5e09dSSadaf Ebrahimi3) Keep several capabilities
55*8dd5e09dSSadaf Ebrahimi   ```c
56*8dd5e09dSSadaf Ebrahimi   capng_clear(CAPNG_SELECT_BOTH);
57*8dd5e09dSSadaf Ebrahimi   capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETUID, CAP_SETGID, -1);
58*8dd5e09dSSadaf Ebrahimi   capng_apply(CAPNG_SELECT_BOTH);
59*8dd5e09dSSadaf Ebrahimi   ```
60*8dd5e09dSSadaf Ebrahimi
61*8dd5e09dSSadaf Ebrahimi4) Check if you have any capabilities
62*8dd5e09dSSadaf Ebrahimi   ```c
63*8dd5e09dSSadaf Ebrahimi   if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE)
64*8dd5e09dSSadaf Ebrahimi       do_something();
65*8dd5e09dSSadaf Ebrahimi   ```
66*8dd5e09dSSadaf Ebrahimi
67*8dd5e09dSSadaf Ebrahimi5) Check for a specific capability
68*8dd5e09dSSadaf Ebrahimi   ```c
69*8dd5e09dSSadaf Ebrahimi   if (capng_have_capability(CAPNG_EFFECTIVE, CAP_CHOWN))
70*8dd5e09dSSadaf Ebrahimi       do_something();
71*8dd5e09dSSadaf Ebrahimi   ```
72*8dd5e09dSSadaf Ebrahimi
73*8dd5e09dSSadaf Ebrahimi6) Retain capabilities across a uid change
74*8dd5e09dSSadaf Ebrahimi   ```c
75*8dd5e09dSSadaf Ebrahimi   capng_clear(CAPNG_SELECT_BOTH);
76*8dd5e09dSSadaf Ebrahimi   capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_CHOWN);
77*8dd5e09dSSadaf Ebrahimi   if (capng_change_id(99, 99, CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING))
78*8dd5e09dSSadaf Ebrahimi       error();
79*8dd5e09dSSadaf Ebrahimi   ```
80*8dd5e09dSSadaf Ebrahimi
81*8dd5e09dSSadaf EbrahimiNow, isn't that a lot simpler? Note that the last example takes about 60 lines
82*8dd5e09dSSadaf Ebrahimiof code using the older capabilities library. As of the 0.6 release, there is
83*8dd5e09dSSadaf Ebrahimia m4 macro file to help adding libcap-ng to your autotools config system. In
84*8dd5e09dSSadaf Ebrahimiconfigure.ac, add LIBCAP_NG_PATH. Then in Makefile.am locate the apps that
85*8dd5e09dSSadaf Ebrahimilink to libcap-ng, add $(CAPNG_LDADD) to their LDADD entries. And lastly,
86*8dd5e09dSSadaf Ebrahimisurround the optional capabilities code with #ifdef HAVE_LIBCAP_NG.
87*8dd5e09dSSadaf Ebrahimi
88*8dd5e09dSSadaf EbrahimiPython
89*8dd5e09dSSadaf Ebrahimi------
90*8dd5e09dSSadaf EbrahimiLibcap-ng 0.6 and later has python bindings. (Only python3 is supported from 0.8.4 onward.) You simply add 'import capng' in your script.  Here are the same examples as above in python:
91*8dd5e09dSSadaf Ebrahimi
92*8dd5e09dSSadaf Ebrahimi1) Drop all capabilities
93*8dd5e09dSSadaf Ebrahimi   ```python
94*8dd5e09dSSadaf Ebrahimi   capng.capng_clear(capng.CAPNG_SELECT_BOTH)
95*8dd5e09dSSadaf Ebrahimi   capng.capng_apply(capng.CAPNG_SELECT_BOTH)
96*8dd5e09dSSadaf Ebrahimi   ```
97*8dd5e09dSSadaf Ebrahimi
98*8dd5e09dSSadaf Ebrahimi2) Keep one capability
99*8dd5e09dSSadaf Ebrahimi   ```python
100*8dd5e09dSSadaf Ebrahimi   capng.capng_clear(capng.CAPNG_SELECT_BOTH)
101*8dd5e09dSSadaf Ebrahimi   capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_CHOWN)
102*8dd5e09dSSadaf Ebrahimi   capng.capng_apply(capng.CAPNG_SELECT_BOTH)
103*8dd5e09dSSadaf Ebrahimi   ```
104*8dd5e09dSSadaf Ebrahimi
105*8dd5e09dSSadaf Ebrahimi3) Keep several capabilities
106*8dd5e09dSSadaf Ebrahimi   ```python
107*8dd5e09dSSadaf Ebrahimi   capng.capng_clear(capng.CAPNG_SELECT_BOTH)
108*8dd5e09dSSadaf Ebrahimi   capng.capng_updatev(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_SETUID, capng.CAP_SETGID, -1)
109*8dd5e09dSSadaf Ebrahimi   capng.capng_apply(capng.CAPNG_SELECT_BOTH)
110*8dd5e09dSSadaf Ebrahimi   ```
111*8dd5e09dSSadaf Ebrahimi
112*8dd5e09dSSadaf Ebrahimi4) Check if you have any capabilities
113*8dd5e09dSSadaf Ebrahimi   ```python
114*8dd5e09dSSadaf Ebrahimi   if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS) > capng.CAPNG_NONE:
115*8dd5e09dSSadaf Ebrahimi       do_something()
116*8dd5e09dSSadaf Ebrahimi   ```
117*8dd5e09dSSadaf Ebrahimi
118*8dd5e09dSSadaf Ebrahimi5) Check for a specific capability
119*8dd5e09dSSadaf Ebrahimi   ```python
120*8dd5e09dSSadaf Ebrahimi   if capng.capng_have_capability(capng.CAPNG_EFFECTIVE, capng.CAP_CHOWN):
121*8dd5e09dSSadaf Ebrahimi       do_something()
122*8dd5e09dSSadaf Ebrahimi   ```
123*8dd5e09dSSadaf Ebrahimi
124*8dd5e09dSSadaf Ebrahimi6) Retain capabilities across a uid change
125*8dd5e09dSSadaf Ebrahimi   ```python
126*8dd5e09dSSadaf Ebrahimi   capng.capng_clear(capng.CAPNG_SELECT_BOTH)
127*8dd5e09dSSadaf Ebrahimi   capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_CHOWN)
128*8dd5e09dSSadaf Ebrahimi   if capng.capng_change_id(99, 99, capng.CAPNG_DROP_SUPP_GRP | capng.CAPNG_CLEAR_BOUNDING) < 0:
129*8dd5e09dSSadaf Ebrahimi       error()
130*8dd5e09dSSadaf Ebrahimi   ```
131*8dd5e09dSSadaf Ebrahimi
132*8dd5e09dSSadaf EbrahimiThe one caveat is that printing capabilities from python does not work. But
133*8dd5e09dSSadaf Ebrahimiyou can still manipulate capabilities, though.
134*8dd5e09dSSadaf Ebrahimi
135*8dd5e09dSSadaf EbrahimiAmbient Capabilities
136*8dd5e09dSSadaf Ebrahimi--------------------
137*8dd5e09dSSadaf EbrahimiAmbient capabilities arrived in the 4.3 Linux kernel. Ambient capabilities
138*8dd5e09dSSadaf Ebrahimiallow a privileged process to bestow capabilities to a child process. This
139*8dd5e09dSSadaf Ebrahimiis how systemd grants capabilities to a daemon running in a service account.
140*8dd5e09dSSadaf EbrahimiThe problem with ambient capabilities is they are inherited forever. Every
141*8dd5e09dSSadaf Ebrahimiprocess exec'ed from the original service also has the capabilities. This is
142*8dd5e09dSSadaf Ebrahimia security issue.
143*8dd5e09dSSadaf Ebrahimi
144*8dd5e09dSSadaf EbrahimiTo find and fix this, you can run the pscap program and grep for '@'. The '@'
145*8dd5e09dSSadaf Ebrahimisymbol denotes processes that have ambient capabilities. For example:
146*8dd5e09dSSadaf Ebrahimi
147*8dd5e09dSSadaf Ebrahimi```
148*8dd5e09dSSadaf Ebrahimi# pscap | grep @
149*8dd5e09dSSadaf Ebrahimi1     1655  systemd-oom  systemd-oomd        dac_override, kill @ +
150*8dd5e09dSSadaf Ebrahimi1     1656  systemd-resolve  systemd-resolve     net_raw @ +
151*8dd5e09dSSadaf Ebrahimi
152*8dd5e09dSSadaf Ebrahimi```
153*8dd5e09dSSadaf Ebrahimi
154*8dd5e09dSSadaf EbrahimiTo fix this, libcap-ng 0.8.3 and later ships libdrop_ambient.so.0. It is
155*8dd5e09dSSadaf Ebrahimidesigned to be used with LD_PRELOAD. It has a constructor function that forces
156*8dd5e09dSSadaf Ebrahimithe dropping of ambient capabilities. By the time the application starts, it
157*8dd5e09dSSadaf Ebrahimihas both effective and ambient capabilities - meaning is safe to drop ambient
158*8dd5e09dSSadaf Ebrahimicapabilities very early. You can either link it to an application run as a
159*8dd5e09dSSadaf Ebrahimisystemd service (using ld), or create a wrapper script that then starts the
160*8dd5e09dSSadaf Ebrahimidaemon.
161*8dd5e09dSSadaf Ebrahimi
162*8dd5e09dSSadaf EbrahimiBuilding
163*8dd5e09dSSadaf Ebrahimi--------
164*8dd5e09dSSadaf Ebrahimi
165*8dd5e09dSSadaf EbrahimiAfter cloning libcap-ng, run:
166*8dd5e09dSSadaf Ebrahimi
167*8dd5e09dSSadaf Ebrahimi```
168*8dd5e09dSSadaf Ebrahimicd libcap-ng
169*8dd5e09dSSadaf Ebrahimi./autogen.sh
170*8dd5e09dSSadaf Ebrahimi./configure
171*8dd5e09dSSadaf Ebrahimimake
172*8dd5e09dSSadaf Ebrahimimake install
173*8dd5e09dSSadaf Ebrahimi```
174*8dd5e09dSSadaf Ebrahimi
175*8dd5e09dSSadaf EbrahimiIf you want python bindings, add that option to the configure command. There is also a spec file to use if you are on a rpm based distribution. To do that, run "make dist" instead of make in the above instructions. Then use the resulting tar file with the spec file.
176*8dd5e09dSSadaf Ebrahimi
177*8dd5e09dSSadaf EbrahimiNOTE: to distributions
178*8dd5e09dSSadaf Ebrahimi----------------------
179*8dd5e09dSSadaf EbrahimiThere is a "make check" target. It only works if the available kernel headers
180*8dd5e09dSSadaf Ebrahimiroughly match the build root kernel. Iow, if you have a chroot build system
181*8dd5e09dSSadaf Ebrahimithat is using a much older kernel, the macros in the kernel header files will
182*8dd5e09dSSadaf Ebrahimidescribe functionality that does not exist in the build root. The capng_init
183*8dd5e09dSSadaf Ebrahimifunction will probe the kernel and decide we can only do v1 rather than v3
184*8dd5e09dSSadaf Ebrahimicapabilities instead of what the kernel headers said was possible. If that is
185*8dd5e09dSSadaf Ebrahimiyour case, just don't do the "make check" as part of the build process. This
186*8dd5e09dSSadaf Ebrahimiproblem should go away as build roots eventually switch to the 5.0 or later
187*8dd5e09dSSadaf Ebrahimikernels.
188*8dd5e09dSSadaf Ebrahimi
189*8dd5e09dSSadaf EbrahimiReporting
190*8dd5e09dSSadaf Ebrahimi---------
191*8dd5e09dSSadaf EbrahimiReport any bugs in this package to:
192*8dd5e09dSSadaf Ebrahimihttps://github.com/stevegrubb/libcap-ng/issue
193*8dd5e09dSSadaf Ebrahimi
194