GithubHelp home page GithubHelp logo

stevegrubb / libcap-ng Goto Github PK

View Code? Open in Web Editor NEW
59.0 7.0 35.0 390 KB

Libcap-ng is a library for Linux that makes using posix capabilities easy.

License: GNU General Public License v2.0

Makefile 9.47% Shell 0.10% Python 1.93% M4 7.34% C 75.24% Roff 4.89% SWIG 1.03%
linux security capabilities

libcap-ng's Introduction

libcap-ng

The libcap-ng library should make programming with POSIX capabilities easier. The library has some utilities to help you analyse a system for apps that may have too much privileges.

The 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:

ppid  pid   acct       command          type port  capabilities
1     2295  root       nasd             tcp  8000  full
2323  2383  root       dnsmasq          tcp  53    net_admin, net_raw +
1     2286  root       sshd             tcp  22    full
1     2365  root       cupsd            tcp  631   full
1     2286  root       sshd             tcp6 22    full
1     2365  root       cupsd            tcp6 631   full
2323  2383  root       dnsmasq          udp  53    net_admin, net_raw +
2323  2383  root       dnsmasq          udp  67    net_admin, net_raw +
1     2365  root       cupsd            udp  631   full

After checking the networking apps, you should check all running apps with pscap. If you are a developer and have to give your application CAP_DAC_OVERRIDE, you must be accessing files for which you have no permission to access. This typically can be resolved by having membership in the correct groups. Try to avoid needing CAP_DAC_OVERRIDE...you may as well be root if you need it.

Some application developers have chosen to use file system base capabilities rather than be setuid root and have to drop capabilities. Libcap-ng provides filecap to recursively search directories and show you which ones have capabilities and exactly what those are.

C Examples

As an application developer, there are probably 6 use cases that you are interested in: drop all capabilities, keep one capability, keep several capabilities, check if you have any capabilities at all, check for certain capabilities, and retain capabilities across a uid change.

  1. Drop all capabilities

    capng_clear(CAPNG_SELECT_BOTH);
    capng_apply(CAPNG_SELECT_BOTH);
  2. Keep one capability

    capng_clear(CAPNG_SELECT_BOTH);
    capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_CHOWN);
    capng_apply(CAPNG_SELECT_BOTH);
  3. Keep several capabilities

    capng_clear(CAPNG_SELECT_BOTH);
    capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETUID, CAP_SETGID, -1);
    capng_apply(CAPNG_SELECT_BOTH);
  4. Check if you have any capabilities

    if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE)
        do_something();
  5. Check for a specific capability

    if (capng_have_capability(CAPNG_EFFECTIVE, CAP_CHOWN))
        do_something();
  6. Retain capabilities across a uid change

    capng_clear(CAPNG_SELECT_BOTH);
    capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_CHOWN);
    if (capng_change_id(99, 99, CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING))
        error();

Now, isn't that a lot simpler? Note that the last example takes about 60 lines of code using the older capabilities library. As of the 0.6 release, there is a m4 macro file to help adding libcap-ng to your autotools config system. In configure.ac, add LIBCAP_NG_PATH. Then in Makefile.am locate the apps that link to libcap-ng, add $(CAPNG_LDADD) to their LDADD entries. And lastly, surround the optional capabilities code with #ifdef HAVE_LIBCAP_NG.

Python

Libcap-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:

  1. Drop all capabilities

    capng.capng_clear(capng.CAPNG_SELECT_BOTH)
    capng.capng_apply(capng.CAPNG_SELECT_BOTH)
  2. Keep one capability

    capng.capng_clear(capng.CAPNG_SELECT_BOTH)
    capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_CHOWN)
    capng.capng_apply(capng.CAPNG_SELECT_BOTH)
  3. Keep several capabilities

    capng.capng_clear(capng.CAPNG_SELECT_BOTH)
    capng.capng_updatev(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_SETUID, capng.CAP_SETGID, -1)
    capng.capng_apply(capng.CAPNG_SELECT_BOTH)
  4. Check if you have any capabilities

    if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS) > capng.CAPNG_NONE:
        do_something()
  5. Check for a specific capability

    if capng.capng_have_capability(capng.CAPNG_EFFECTIVE, capng.CAP_CHOWN):
        do_something()
  6. Retain capabilities across a uid change

    capng.capng_clear(capng.CAPNG_SELECT_BOTH)
    capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_CHOWN)
    if capng.capng_change_id(99, 99, capng.CAPNG_DROP_SUPP_GRP | capng.CAPNG_CLEAR_BOUNDING) < 0:
        error()

The one caveat is that printing capabilities from python does not work. But you can still manipulate capabilities, though.

Ambient Capabilities

Ambient capabilities arrived in the 4.3 Linux kernel. Ambient capabilities allow a privileged process to bestow capabilities to a child process. This is how systemd grants capabilities to a daemon running in a service account. The problem with ambient capabilities is they are inherited forever. Every process exec'ed from the original service also has the capabilities. This is a security issue.

To find and fix this, you can run the pscap program and grep for '@'. The '@' symbol denotes processes that have ambient capabilities. For example:

# pscap | grep @
1     1655  systemd-oom  systemd-oomd        dac_override, kill @ +
1     1656  systemd-resolve  systemd-resolve     net_raw @ +

To fix this, libcap-ng 0.8.3 and later ships libdrop_ambient.so.0. It is designed to be used with LD_PRELOAD. It has a constructor function that forces the dropping of ambient capabilities. By the time the application starts, it has both effective and ambient capabilities - meaning is safe to drop ambient capabilities very early. You can either link it to an application run as a systemd service (using ld), or create a wrapper script that then starts the daemon.

Building

After cloning libcap-ng, run:

cd libcap-ng
./autogen.sh
./configure
make
make install

If 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.

NOTE: to distributions

There is a "make check" target. It only works if the available kernel headers roughly match the build root kernel. Iow, if you have a chroot build system that is using a much older kernel, the macros in the kernel header files will describe functionality that does not exist in the build root. The capng_init function will probe the kernel and decide we can only do v1 rather than v3 capabilities instead of what the kernel headers said was possible. If that is your case, just don't do the "make check" as part of the build process. This problem should go away as build roots eventually switch to the 5.0 or later kernels.

Reporting

Report any bugs in this package to: https://github.com/stevegrubb/libcap-ng/issue

libcap-ng's People

Contributors

bigon avatar bwncp avatar dagrh avatar dcantrell avatar ericonr avatar ffontaine avatar havardaasen avatar jpalus avatar kloczek avatar masatake avatar ncopa avatar neheb avatar ntkme avatar orbea avatar qazerlab avatar rh-steve-grubb avatar rpurdie avatar sjlc avatar stevegrubb avatar twoerner avatar vapier avatar yixiangzhike avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

libcap-ng's Issues

Warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare] in lookup_table.c and cap-ng.c

During compilation of libcap-ng 0.7.10 for OpenWrt, I noticed these warnings and I think that it could be good that you will know about them.

In file lookup_table.c

lookup_table.c: In function 'capng_capability_to_name':
lookup_table.c:35:27: warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare]
 #define cap_valid(x) ((x) <= last_cap)
                           ^~
lookup_table.c:114:7: note: in expansion of macro 'cap_valid'
  if (!cap_valid(capability))
       ^~~~~~~~~
lookup_table.c:117:6: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
  ptr = capng_lookup_number(captab, captab_msgstr.str,

In file lookup_table.c

cap-ng.c: In function 'capng_update':
cap-ng.c:72:27: warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare]
 #define cap_valid(x) ((x) <= last_cap)
                           ^~
cap-ng.c:452:7: note: in expansion of macro 'cap_valid'
  if (!cap_valid(capability)) {
       ^~~~~~~~~
cap-ng.c: In function 'capng_updatev':
cap-ng.c:72:27: warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare]
 #define cap_valid(x) ((x) <= last_cap)
                           ^~
cap-ng.c:499:9: note: in expansion of macro 'cap_valid'
  while (cap_valid(cap)) {
         ^~~~~~~~~
cap-ng.c: In function 'capng_have_capability':
cap-ng.c:72:27: warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare]
 #define cap_valid(x) ((x) <= last_cap)
                           ^~
cap-ng.c:883:7: note: in expansion of macro 'cap_valid'
  if (!cap_valid(capability))
       ^~~~~~~~~

libcap-ng used by "/usr/sbin/mount.cifs" failed due to not having CAP_SETPCAP in capng_apply

This service:
/etc/systemd/system/servers.service
[Unit]
Description=mount-servers systemd service.

[Service]
Type=simple
ExecStart=/bin/bash /usr/local/bin/mount-servers.sh

[Install]
WantedBy=multi-user.target


This script:
#!/bin/bash

mount -t cifs //192.168.1.200/Drive_E /mnt/server-e -o credentials=/root/.smbcredentials_server,nounix,dir_mode=0777,file_mode=0777
mount -t cifs //192.168.1.200/Drive_E/Dropbox /mnt/dropbox -o credentials=/root/.smbcredentials_server,nounix,dir_mode=0777,file_mode=0777
mount -t cifs //192.168.1.200/Drive_D /mnt/server-d -o credentials=/root/.smbcredentials_server,nounix,dir_mode=0777,file_mode=0777


systemctl status servers
× servers.service - mount-servers systemd service.
Loaded: loaded (/usr/local/lib/systemd/system/servers.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Tue 2021-09-07 17:30:38 PDT; 44min ago
Process: 13728 ExecStart=/bin/bash /usr/local/bin/mount-servers.sh (code=exited, status=32)
Main PID: 13728 (code=exited, status=32)
CPU: 15ms

Sep 07 17:30:38 fedora bash[13735]: mount error(16): Device or resource busy
Sep 07 17:30:38 fedora bash[13735]: Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)
Sep 07 17:30:38 fedora mount.cifs[13739]: libcap-ng used by "/usr/sbin/mount.cifs" failed due to not having CAP_SETPCAP in capng_apply
Sep 07 17:30:38 fedora bash[13738]: mount error(16): Device or resource busy
Sep 07 17:30:38 fedora bash[13738]: Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)
Sep 07 17:30:38 fedora bash[13740]: mount: /mnt/data: /dev/sdb1 already mounted on /mnt/backup.
Sep 07 17:30:38 fedora bash[13741]: mount: /mnt/backup: /dev/sdc1 already mounted on /mnt/data.
Sep 07 17:30:38 fedora bash[13742]: mount: /mnt/timeshift: /dev/sdd1 already mounted on /mnt/timeshift.
Sep 07 17:30:38 fedora systemd[1]: servers.service: Main process exited, code=exited, status=32/n/a
Sep 07 17:30:38 fedora systemd[1]: servers.service: Failed with result 'exit-code'.

Sep 07 17:30:38 fedora bash[13735]: mount error(16): Device or resource busy
Sep 07 17:30:38 fedora bash[13735]: Refer to the mount.cifs(8) manual page (e.g>
Sep 07 17:30:38 fedora mount.cifs[13739]: libcap-ng used by "/usr/sbin/mount.ci>
Sep 07 17:30:38 fedora bash[13738]: mount error(16): Device or resource busy
Sep 07 17:30:38 fedora bash[13738]: Refer to the mount.cifs(8) manual page (e.g>
Sep 07 17:30:38 fedora bash[13740]: mount: /mnt/data: /dev/sdb1 already mounted>
Sep 07 17:30:38 fedora bash[13741]: mount: /mnt/backup: /dev/sdc1 already mount>
Sep 07 17:30:38 fedora bash[13742]: mount: /mnt/timeshift: /dev/sdd1 already mo>
Sep 07 17:30:38 fedora systemd[1]: servers.service: Main process exited, code=e>
Sep 07 17:30:38 fedora systemd[1]: servers.service: Failed with result 'exit-co>
lines 1-17/17 (END)

capng_updatev (python) doesnt work

The following code resulted in the wrong capabilities

capng.capng_updatev(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_SYS_BOOT, capng.CAP_SYS_TIME, -1)
capng.capng_change_id(pwent.pw_uid, pwent.pw_gid, capng.CAPNG_CLEAR_BOUNDING)

I expected sys_boot and sys_time in the capabilities of my running Python process, but ...

> pscap 
1191  5634  ted         python3             chown, sys_boot

I ended up instead with the following

for c in [ capng.CAP_SYS_BOOT, capng.CAP_SYS_TIME ]:
    capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, c)
capng.capng_change_id(pwent.pw_uid, pwent.pw_gid, capng.CAPNG_CLEAR_BOUNDING)

which worked fine:

> pscap 
1207  5634  ted         python3             sys_boot, sys_time

Linux kernel version is 5.4.51. Host is armv7l. libcap-ng version 0.7.10

`capng_apply` does not notice it failed to apply a capability

A complete ready-to-go repro is here:
https://gist.github.com/snarkmaster/4d019ab39e9adbe4fd7269f4f9812692

The short story is this:

  • start with full capabilities -- the last byte of the bounding set in /proc/PID/status is ff
  • run capsh --drop=cap_chown -- -- the last byte is now fe
  • under the capsh run a libcap-ng` program which tries to set the bounding set to full again
  • capng_apply succeeds
  • after applying, run capng_have_capability(CAPNG_BOUNDING_SET, CAP_CHOWN) -- the result is 1
  • but if I look at procfs, the last byte still ends in fe (of course).

0.8.4: autoreconf fails

Looks like something is wrong

+ cd libcap-ng-0.8.4
+ autoreconf -fiv
autoreconf: export WARNINGS=
autoreconf: Entering directory '.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy --force
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: copying file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltoptions.m4'
libtoolize: copying file 'm4/ltsugar.m4'
libtoolize: copying file 'm4/ltversion.m4'
libtoolize: copying file 'm4/lt~obsolete.m4'
autoreconf: configure.ac: not using Intltool
autoreconf: configure.ac: not using Gtkdoc
autoreconf: running: aclocal --force -I m4
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
configure.ac:42: installing './compile'
configure.ac:40: installing './config.guess'
configure.ac:40: installing './config.sub'
configure.ac:41: installing './install-sh'
configure.ac:41: installing './missing'
Makefile.am: error: required file './NEWS' not found
bindings/python3/Makefile.am: installing './depcomp'
bindings/python3/Makefile.am:31: installing './py-compile'
parallel-tests: installing './test-driver'
bindings/src/Makefile.am:24: warning: variable 'SWIG_SOURCES' is defined but no program or
bindings/src/Makefile.am:24: library has 'SWIG' as canonical name (possible typo)
autoreconf: error: automake failed with exit status: 1

It does not work with autoconf 2.71 and 2.72.

Problem with namespaces

libcap-ng seems to have some problem with namespaces. I am working with a container infrastructure like docker and i have written code to drop capabilites inside the container. It doesn't work when i enable both namespaces and resources. But it works when i do resource-only.

undefined reference to `pthread_atfork'

Building on some distros (openSUSE 15.1) requires the addition of -lpthread in order to build successfully:

make[2]: Entering directory '/home/trevor/devel/extern/libcap-ng/_build/utils'
/bin/sh ../libtool  --tag=CC   --mode=link gcc -W -Wall -Wshadow -Wformat -Wundef -D_GNU_SOURCE -g -O2   -o pscap pscap.o  -L../src -lcap-ng
libtool: link: gcc -W -Wall -Wshadow -Wformat -Wundef -D_GNU_SOURCE -g -O2 -o .libs/pscap pscap.o  -L../src /home/trevor/devel/extern/libcap-ng/_build/src/.libs/libcap-ng.so
/usr/lib64/gcc/x86_64-suse-linux/8/../../../../x86_64-suse-linux/bin/ld: /home/trevor/devel/extern/libcap-ng/_build/src/.libs/libcap-ng.so: undefined reference to `pthread_atfork'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:488: pscap] Error 1
make[2]: Leaving directory '/home/trevor/devel/extern/libcap-ng/_build/utils'
make[1]: *** [Makefile:448: all-recursive] Error 1
make[1]: Leaving directory '/home/trevor/devel/extern/libcap-ng/_build'
make: *** [Makefile:380: all] Error 2

I noticed this with 0.7.10, but the issue also exists on master.

I can build successfully if I do:

$ make LDFLAGS="-lpthread"

Misleading output in configure

--- configure.ac.orig   2023-04-27 22:18:57.659402571 -0400
+++ configure.ac        2023-04-27 22:19:07.173321549 -0400
@@ -60,7 +60,7 @@
        [AC_SEARCH_LIBS(pthread_atfork, pthread)],
        [AC_MSG_WARN(pthread.h not found, disabling pthread_atfork.)])
 AC_CHECK_HEADERS(sys/vfs.h, [
-       AC_CHECK_HEADERS(linux/magic.h, [] [AC_MSG_WARN(linux/magic.h is required in order to verify procfs.)])
+       AC_CHECK_HEADERS(linux/magic.h, [], [AC_MSG_WARN(linux/magic.h is required in order to verify procfs.)])
        ], [AC_MSG_WARN(sys/vfs.h is required in order to verify procfs.)])

 AC_ARG_WITH([capability_header],

capng_change_id() can leave PR_SET_KEEPCAPS set to 1 on failure

While working on adding capability support for openvpn, we discovered a very problematic possible failure case of capng_change_id():

In case capng_update_id() fails, maybe due to missing capabilities, rampant SElinux, or whatever other reason, we fall back to the classic codepath, which just calls setgid() + setuid().
Now, if capng_change_id() fails after

if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0))
but before actually having changed the user in
rc = setresuid(uid, uid, uid);
we are left with PR_SET_KEEPCAPS set.

This results in our fallback setuid() leaving the permitted capabilities set. This is a very unexpected and potentially dangerous if it's a security critical process that is expected to have no capabilities.

Is this behaviour expected? As in, we should always terminate in case capng_change_id() failed, since the state cannot be guaranteed?
Or would it be possible to reset the PR_SET_KEEPCAPS flags on failure? Or maybe set it much later, so there's not so much stuff that can fail in between it and the actual setuid?

Upgrade to libcap-ng 0.8.1 breaks GNOME Keyring and other projects

After upgrading libcap-ng to the freshly released version 0.8.1, attempting to start GNOME Keyring fails with an error message:

$ gnome-keyring-daemon --start
gnome-keyring-daemon: error dropping process capabilities, aborting

I have bisected this to commit 6a24a9c ("capng_apply error update"), so apparently GNOME Keyring does not expect capng_apply to fail in this situation. The relevant capability handling code in GNOME Keyring looks as follows:

capng_clear (CAPNG_SELECT_BOTH);
if (capng_update (CAPNG_ADD,
                  CAPNG_EFFECTIVE|CAPNG_PERMITTED,
                  CAP_IPC_LOCK) != 0)
	early_error ("error dropping process capabilities");
if (capng_apply (CAPNG_SELECT_BOTH) != 0)
	early_error ("error dropping process capabilities");

Downstream Arch Linux bug report: FS#68664

Improve last cap detection

Hi! I'm developing some changes in util-linux ( util-linux/util-linux#1187 ) for how they detect the last cap from the kernel, and I would like to know if you'd accept a PR to add the same changes here.

Also, do you think a capng_get_last_cap call could be added to the API?

capng_get_caps_process vs sandbox

Hi,
I've got a heavily sandbox'd daemon that runs something like:
a) Sandbox
b) Create more threads
c) Do stuff in threads

The sandbox includes a mount namespace setup where it doesn't have /proc.
capng_get_caps_process calls get_bounding_set which reads /proc/.../state - which fails.
That's not a problem with yee oldee libcaps, it only uses capget.
So now I have a problem how to setup each thread; the current guess is to do a capng_save_state before the sandboxing, and then do a restore state somewhere in each thread.
Which is kind of OK except for restore_state freeing stuff; so I'm going to have to do a dance of restore_state/save_state to keep a copy.

It feels like there should be a better way.

Detect kernel support of PR_CAP_AMBIENT at runtime

The issue I'm facing is that I have containers build with 5.x kernel headers, and the kernel versions I need to support for actual deployment is ranging between 4.1 - 5.x, which is a mix of kernels that may and may not support PR_CAP_AMBIENT.

Building the support of PR_CAP_AMBIENT then run libcap-ng on kernel without actual support would fail almost every function. Build different versions of containers with different kernel headers is not ideal.

If we can detect the support of PR_CAP_AMBIENT at runtime instead of compile time then we can conditionally run code related to PR_CAP_AMBIENT, thus a single build of libcap-ng using new kernel headers can run on both old and new kernel without causing problem.

I'm not really a C programmer, but I imagine we can do something like this:

#ifdef PR_CAPBSET_DROP
int has_capbset_drop = 1;
rc = prctl(PR_CAPBSET_READ, 0, 0, 0, 0);
if (rc < 0 && errno == EINVAL) { // EINVAL -> kernel does not support PR_CAPBSET_DROP
  has_capbset_drop = 0;
}
if (has_capbset_drop) {
  ...
}
#endif

#ifdef PR_CAP_AMBIENT
int has_ambient = 1;
rc = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, 0, 0, 0);
if (rc < 0 && errno == EINVAL) { // EINVAL -> kernel does not support PR_CAP_AMBIENT
  has_ambient = 0;
}
if (has_ambient) {
  ...
}
#endif

I'd happy to make a PR, but I want to hear some thoughts before I proceed.

`capng_apply` applies ambient caps too early?

This will leave the ambient caps unset:

    capng_clear(CAPNG_SELECT_ALL);  // traditional, bounding, ambient
    capng_update(
        CAPNG_ADD, 
        CAPNG_EFFECTIVE | CAPNG_PERMITTED | CAPNG_INHERITABLE
            | CAPNG_BOUNDING_SET | CAPNG_AMBIENT, 
        CAP_CHOWN
    );
    capng_apply(CAPNG_SELECT_ALL);  // traditional, bounding, ambient

I.e. /proc/self/status will have:

CapInh: 0000000000000001
CapPrm: 0000000000000001
CapEff: 0000000000000001
CapBnd: 0000000000000001
CapAmb: 0000000000000000

But if you double up the capng_apply, you get the desired result:

    capng_apply(CAPNG_SELECT_ALL);  // traditional, bounding
    capng_apply(CAPNG_SELECT_ALL);  // ambient

I think this happens because of the line in capabilities (7) that says:

The ambient capability set obeys the invariant that no capability can ever be ambient if it is not both permitted and inheritable.

libdrop_ambient breaks compile if PR_CAP_AMBIENT is undefined

In cap-ng.c all uses of PR_CAP_AMBIENT are protected by #ifdef PR_CAP_AMBIENT but libdrop_ambient.c does not have the check. Of course libdrop_ambient is useless on platforms that don't have ambient capability support, but I propose just adding the ifdef there instead of trying to tinker the autotools files to skip building the library altogether when the support is missing (which shoould be pretty rare case by now).

What do you think? Would you accept a pull request for something like this?

--- a/src/libdrop_ambient.c     2020-11-18 10:39:31.000000000 -0800
+++ b/src/libdrop_ambient.c     2020-12-02 15:59:10.977235659 -0800
@@ -25,6 +25,8 @@
 
 void __attribute__ ((constructor)) init(void)
 {
+#ifdef PR_CAP_AMBIENT
        prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
+#endif
 }

python bindings install fails if `python` binary is missing

Although python3 binary was detected as valid interpreter, install still failed due to missing python binary:

../../py-compile[155]: python: inaccessible or not found
make[4]: *** [Makefile:551: install-pyexecPYTHON] Error 127

Version: 0.8.5

Why to modify capng_updatev parameter type to signed for python bindings

In C code,the parameters of capng_updatev are parsed as 'unsigned int' like this:
int capng_updatev(capng_act_t action, capng_type_t type,
unsigned int capability, ...)
{
int rc;
unsigned int cap;
va_list ap;

rc = capng_update(action, type, capability);
if (rc)
	return rc;
va_start(ap, capability);
cap = va_arg(ap, unsigned int);
while (cap_valid(cap)) {
	rc = capng_update(action, type, cap);
	if (rc)
		break;
	cap = va_arg(ap, unsigned int);
}
va_end(ap);

// See if planned exit or invalid
if (cap == (unsigned)-1)
	rc = 0;
else {
	rc = -1;
	errno = EINVAL;
}

return rc;

}

In the commit 2906fb0 ,they were changed to signed, Why to modify capng_updatev parameter type to signed for python bindings?

httpd segfaults on graceful reload (fork()) with 0.7.9

Here apache 2.4.33 segfaults on graceful reload in some conditions (like php pgsql or curl loaded)

0.7.8 - works fine
0.7.9 - segfault

I guess "Use pthread_atfork to optionally reset the pid and related info on fork" is problematic.

Core was generated by `/usr/sbin/httpd -f /etc/httpd/apache.conf'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fd94d9a36a0 in ?? ()
(gdb) bt
#0  0x00007fd94d9a36a0 in ?? ()
#1  0x00007fd961a8b52e in __libc_fork () at ../sysdeps/nptl/fork.c:204
#2  0x00007fd95dcc1a55 in ?? () from /etc/httpd/modules/mod_mpm_prefork.so
#3  0x00007fd95dcc2a3e in ?? () from /etc/httpd/modules/mod_mpm_prefork.so
#4  0x00000000004356c3 in ap_run_mpm ()
#5  0x000000000042e06c in main ()

glibc fork.c part is

   197        /* Reset the lock the dynamic loader uses to protect its data.  */
   198        __rtld_lock_initialize (GL(dl_load_lock));
   199  
   200        /* Run the handlers registered for the child.  */
   201        while (allp != NULL)
   202          {
   203            if (allp->handler->child_handler != NULL)
   204              allp->handler->child_handler ();
   205  
   206            /* Note that we do not have to wake any possible waiter.
   207               This is the only thread in the new process.  The count
   208               may have been bumped up by other threads doing a fork.
   209               We reset it to 1, to avoid waiting for non-existing
   210               thread(s) to release the count.  */
   211            allp->handler->refcntr = 1;

apache isn't directly using libcap-ng but is loading php->pgsql->postgresql-libs->openldap-libs->cyrus-sasl/audit-libs->libcap-ng, so after all libcap-ng code is used

That could explain things:
https://sourceware.org/bugzilla/show_bug.cgi?id=13502
as graceful apache restart reloads modules.

Looks like using pthread_atfork isn't good choice: "the whole concept of pthread_atfork was a mistake, and this is largely acknowledged in the Rationale section for pthread_atfork in POSIX."

Build of libcap-ng failed with SWIG 4.2.0

I am testing rebuild of SWIG dependencies against version 4.2.0 in Fedora rawhide/40.

The build of libcap-ng-0.8.4 is failing with this version.

swig -o capng_wrap.c -python -I. -I../.. -I/usr/include/python3.12 -I/usr/include/python3.12 ./../src/capng_swig.i
make[4]: Leaving directory '/builddir/build/BUILD/libcap-ng-0.8.4/bindings/python3'
./../src/capng_swig.i:33: Error: Unknown directive '%except'.
make[4]: *** [Makefile:878: capng_wrap.c] Error 1
make[3]: *** [Makefile:595: all-recursive] Error 1
make[2]: *** [Makefile:390: all-recursive] Error 1
make[1]: *** [Makefile:441: all-recursive] Error 1
make: *** [Makefile:373: all] Error 2
error: Bad exit status from /var/tmp/rpm-tmp.98V4Nl (%build)

The reason is that features deprecated in SWIG 1.x and 2.x was removed. Instead %except should be replaced by using %exception.

Tarball distribution issues.

This is mostly for build environments and automated handling / downloading.

people.redhat.com is currently having issues. Redhat internal tracking ID: INC2158974
https://www.ssllabs.com/ssltest/analyze.html?d=people.redhat.com
The certificate chain is incomplete, leading to download issues if the certificate chain isn't ignored.

I was thinking of moving the libcap-ng download URL to github, but the github tarballs don't hash the same as the release tarballs.
I suspect these ones distributed here are just source balls, not "make dist" ones.

Either way, it currently causes a bit of a headache.
If it's an option, could you please distribute the proper release tarballs on github and make it a permanent hosting place?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.