]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: allow using virCommandAllowCap with setuid helpers
authorPaolo Bonzini <pbonzini@redhat.com>
Mon, 25 Mar 2013 14:25:29 +0000 (15:25 +0100)
committerEric Blake <eblake@redhat.com>
Thu, 18 Apr 2013 20:52:23 +0000 (14:52 -0600)
When running unprivileged, virSetUIDGIDWithCaps will fail because it
tries to add the requested capabilities to the permitted and effective
sets.

Detect this case, and invoke the child with cleared permitted and
effective sets.  If it is a setuid program, it will get them.

Some care is needed also because you cannot drop capabilities from the
bounding set without CAP_SETPCAP.  Because of that, ignore errors from
setting the bounding set.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
src/util/virutil.c

index 6f37c06c9f3eb2de8dfd1d6a7aed92729d9e572a..9cc36721f52dcc4dc9e8c6bebaff54fd8d8c22a8 100644 (file)
@@ -3053,9 +3053,21 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, unsigned long long capBits,
 
     /* Change to the temp capabilities */
     if ((capng_ret = capng_apply(CAPNG_SELECT_CAPS)) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("cannot apply process capabilities %d"), capng_ret);
-        goto cleanup;
+        /* Failed.  If we are running unprivileged, and the arguments make sense
+         * for this scenario, assume we're starting some kind of setuid helper:
+         * do not set any of capBits in the permitted or effective sets, and let
+         * the program get them on its own.
+         *
+         * (Too bad we cannot restrict the bounding set to the capabilities we
+         * would like the helper to have!).
+         */
+        if (getuid() > 0 && clearExistingCaps && !need_setuid && !need_setgid) {
+            capng_clear(CAPNG_SELECT_CAPS);
+        } else {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("cannot apply process capabilities %d"), capng_ret);
+            goto cleanup;
+        }
     }
 
     if (virSetUIDGID(uid, gid) < 0)