提交 7a2e845a 编写于 作者: L Laine Stump

util: maintain caps when running command with uid != 0

virCommand was previously calling virSetUIDGID() to change the uid and
gid of the child process, then separately calling
virSetCapabilities(). This did not work if the desired uid was != 0,
since a setuid to anything other than 0 normally clears all
capabilities bits.

The solution is to use the new virSetUIDGIDWithCaps(), sending it the
uid, gid, and capabilities bits. This will get the new process setup
properly.

Since the static functions virSetCapabilities() and
virClearCapabilities are no longer called, they have been removed.

NOTE: When combined with "filecap $path-to-qemu sys_rawio", this patch
will make CAP_SYS_RAWIO (which is required for passthrough of generic
scsi commands to a guest - see commits e8daeeb1, 177db087, 397e6a70, and
74e03496) be retained by qemu when necessary. Apparently that
capability has been broken for non-root qemu ever since it was
originally added.
上级 e11451f4
......@@ -182,65 +182,6 @@ virCommandFDSet(int fd,
#ifndef WIN32
static int virClearCapabilities(void) ATTRIBUTE_UNUSED;
# if WITH_CAPNG
static int virClearCapabilities(void)
{
int ret;
capng_clear(CAPNG_SELECT_BOTH);
if ((ret = capng_apply(CAPNG_SELECT_BOTH)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot clear process capabilities %d"), ret);
return -1;
}
return 0;
}
/**
* virSetCapabilities:
* @capabilities - capability flag to set.
* In case of 0, this function is identical to
* virClearCapabilities()
*
*/
static int virSetCapabilities(unsigned long long capabilities)
{
int ret, i;
capng_clear(CAPNG_SELECT_BOTH);
for (i = 0; i <= CAP_LAST_CAP; i++) {
if (capabilities & (1ULL << i))
capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i);
}
if ((ret = capng_apply(CAPNG_SELECT_BOTH)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot apply process capabilities %d"), ret);
return -1;
}
return 0;
}
# else
static int virClearCapabilities(void)
{
// VIR_WARN("libcap-ng support not compiled in, unable to clear "
// "capabilities");
return 0;
}
static int
virSetCapabilities(unsigned long long capabilities ATTRIBUTE_UNUSED)
{
return 0;
}
# endif
/**
* virFork:
* @pid - a pointer to a pid_t that will receive the return value from
......@@ -645,19 +586,17 @@ virExec(virCommandPtr cmd)
}
# endif
if (cmd->uid != (uid_t)-1 || cmd->gid != (gid_t)-1) {
VIR_DEBUG("Setting child uid:gid to %d:%d",
(int)cmd->uid, (int)cmd->gid);
if (virSetUIDGID(cmd->uid, cmd->gid) < 0)
/* The steps above may need to do something privileged, so we delay
* setuid and clearing capabilities until the last minute.
*/
if (cmd->uid != (uid_t)-1 || cmd->gid != (gid_t)-1 ||
cmd->capabilities || (cmd->flags & VIR_EXEC_CLEAR_CAPS)) {
VIR_DEBUG("Setting child uid:gid to %d:%d with caps %llx",
(int)cmd->uid, (int)cmd->gid, cmd->capabilities);
if (virSetUIDGIDWithCaps(cmd->uid, cmd->gid, cmd->capabilities) < 0)
goto fork_error;
}
/* The steps above may need todo something privileged, so
* we delay clearing capabilities until the last minute */
if (cmd->capabilities || (cmd->flags & VIR_EXEC_CLEAR_CAPS))
if (virSetCapabilities(cmd->capabilities) < 0)
goto fork_error;
if (cmd->pwd) {
VIR_DEBUG("Running child in %s", cmd->pwd);
if (chdir(cmd->pwd) < 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册