The need_prctl variable is not really needed. If it is false, capng_apply will be called twice with the same set, causing a little extra work but no problem. This keeps the code a bit simpler. It is also clearer to invoke capng_apply(CAPNG_SELECT_BOUNDS) separately, to make sure it is done while we have CAP_SETPCAP. Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- src/util/virutil.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/util/virutil.c b/src/util/virutil.c index 42b4295..36e6cee 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -3003,7 +3003,7 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, unsigned long long capBits, { int ii, capng_ret, ret = -1; bool need_setgid = false, need_setuid = false; - bool need_prctl = false, need_setpcap = false; + bool need_setpcap = false; /* First drop all caps (unless the requested uid is "unchanged" or * root and clearExistingCaps wasn't requested), then add back @@ -3043,17 +3043,15 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, unsigned long long capBits, capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETPCAP); # endif - need_prctl = capBits || need_setgid || need_setuid || need_setpcap; - /* Tell system we want to keep caps across uid change */ - if (need_prctl && prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { virReportSystemError(errno, "%s", _("prctl failed to set KEEPCAPS")); goto cleanup; } /* Change to the temp capabilities */ - if ((capng_ret = capng_apply(CAPNG_SELECT_BOTH)) < 0) { + if ((capng_ret = capng_apply(CAPNG_SELECT_CAPS)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot apply process capabilities %d"), capng_ret); goto cleanup; @@ -3063,12 +3061,18 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, unsigned long long capBits, goto cleanup; /* Tell it we are done keeping capabilities */ - if (need_prctl && prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0)) { + if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0)) { virReportSystemError(errno, "%s", _("prctl failed to reset KEEPCAPS")); goto cleanup; } + /* Set bounding set while we have CAP_SETPCAP. Unfortunately we cannot + * do this if we failed to get the capability above, so ignore the + * return value. + */ + capng_apply(CAPNG_SELECT_BOUNDS); + /* Drop the caps that allow setuid/gid (unless they were requested) */ if (need_setgid) capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETGID); @@ -3078,7 +3082,7 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, unsigned long long capBits, if (need_setpcap) capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETPCAP); - if (need_prctl && ((capng_ret = capng_apply(CAPNG_SELECT_BOTH)) < 0)) { + if (((capng_ret = capng_apply(CAPNG_SELECT_CAPS)) < 0)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot apply process capabilities %d"), capng_ret); ret = -1; -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list