audit is using cap-ng itself since version 2.6.1, and it gets to initialize the internal state of the cap-ng library before we call fork(). Because of that, our own use of cap-ng in the child process ends up attempting to change the capabilities of the parent process instead of the child process, which fails. Calling capng_setpid() before using any other cap-ng API ensures we're altering the capabilities of the right process. --- src/util/virutil.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/util/virutil.c b/src/util/virutil.c index 170dd59..d393a12 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -1465,6 +1465,14 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, gid_t *groups, int ngroups, bool need_setgid = false, need_setuid = false; bool need_setpcap = false; + /* The cap-ng library stores some internal data in a thread local + * variable; that includes the PID of the process it should alter + * the capabilities of. After fork(), this data is not cleared, + * so we might end up trying to change the capabilities of a + * different process. Initialize the PID explicitly to work around + * that issue */ + capng_setpid(getpid()); + /* First drop all caps (unless the requested uid is "unchanged" or * root and clearExistingCaps wasn't requested), then add back * those in capBits + the extra ones we need to change uid/gid and -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list