[libvirt] [PATCH] lxc: Add virCgroupSetOwner()
Richard Weinberger
richard at nod.at
Fri Feb 14 07:47:37 UTC 2014
Am 14.02.2014 08:10, schrieb Martin Kletzander:
> On Thu, Feb 13, 2014 at 05:15:22PM +0000, Daniel P. Berrange wrote:
>> From: Richard Weinberger <richard at nod.at>
>>
>> Add a new helper function to change the permissions of a control
>> group. This function is needed for user namespaces, we need to
>> chmod() the cgroup to the initial uid/gid such that systemd is
>> allowed to use the cgroup.
>>
>> Only the systemd controller is made accessible to the container.
>> Others must remain read-only since it is generally not safe
>> to delegate resource controller write access to unprivileged
>> processes.
>>
>> Signed-off-by: Richard Weinberger <richard at nod.at>
>> ---
>> src/libvirt_private.syms | 1 +
>> src/lxc/lxc_cgroup.c | 9 ++++++++
>> src/util/vircgroup.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
>> src/util/vircgroup.h | 5 +++++
>> 4 files changed, 69 insertions(+)
>>
>> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
>> index 0b28bac..cfa9f75 100644
>> --- a/src/libvirt_private.syms
>> +++ b/src/libvirt_private.syms
>> @@ -1056,6 +1056,7 @@ virCgroupSetMemory;
>> virCgroupSetMemoryHardLimit;
>> virCgroupSetMemorySoftLimit;
>> virCgroupSetMemSwapHardLimit;
>> +virCgroupSetOwner;
>> virCgroupSupportsCpuBW;
>>
>>
>> diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
>> index cc0d5e8..0d0d9c0 100644
>> --- a/src/lxc/lxc_cgroup.c
>> +++ b/src/lxc/lxc_cgroup.c
>> @@ -484,6 +484,15 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def)
>> &cgroup) < 0)
>> goto cleanup;
>>
>> + /* setup control group permissions for user namespace */
>> + if (def->idmap.uidmap) {
>> + if (virCgroupSetOwner(cgroup,
>> + def->idmap.uidmap[0].target,
>> + def->idmap.gidmap[0].target,
>> + (1 << VIR_CGROUP_CONTROLLER_SYSTEMD)))
>
> This should be "if (virCgroupSetOwner() < 0)" to go with the rest.
Ok.
>> + goto cleanup;
>> + }
>> +
>
> virCgroupNewMachine() guarantees that the cgroup is NULL in case of an
> error, but you don't guarantee that in virCgroupSetOwner(), so the
> errors from it won't propagate anywhere, because you don't return NULL
> from this function.
Do we really want to treat a failed chown() as fatal error?
>> cleanup:
>> return cgroup;
>> }
>> diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
>> index a6d60c5..2dc6986 100644
>> --- a/src/util/vircgroup.c
>> +++ b/src/util/vircgroup.c
>> @@ -3253,6 +3253,60 @@ cleanup:
>> }
>>
>>
>> +int virCgroupSetOwner(virCgroupPtr cgroup,
>> + uid_t uid,
>> + gid_t gid,
>> + int controllers)
>> +{
>> + size_t i;
>> +
>> + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
>> + char *base, *entry;
>> + DIR *dh;
>> + struct dirent *de;
>> +
>> + if (!((1 << i) & controllers))
>> + continue;
>> +
>> + if (!cgroup->controllers[i].mountPoint)
>> + continue;
>> +
>> + if (virAsprintf(&base, "%s%s", cgroup->controllers[i].mountPoint,
>> + cgroup->controllers[i].placement) < 0) {
>> + virReportOOMError();
>
> Double OOM reporting.
Ahh, virAsprintf() already reports the error...
>> + return -1;
>> + }
>> +
>> + dh = opendir(base);
>> + while ((de = readdir(dh)) != NULL) {
>> + if (STREQ(de->d_name, ".") ||
>> + STREQ(de->d_name, ".."))
>> + continue;
>> +
>> + if (virAsprintf(&entry, "%s/%s", base, de->d_name) < 0) {
>> + VIR_FREE(base);
>> + virReportOOMError();
>
> Same here, plus you continue the loop and don't return -1.
Ok!
>> + }
>> +
>> + if (chown(entry, uid, gid) < 0)
>> + virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
>> + entry, uid, gid);
>
> Indentation's off and you continue the loop again.
I continue here by design because I don't treat a failed chown() as fatal error.
>> +
>> + VIR_FREE(entry);
>> + }
>> + closedir(dh);
>> +
>> + if (chown(base, uid, gid) < 0)
>> + virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
>> + base, uid, gid);
>
> Again reporting an error, but returning 0 even in case of an error.
Same here.
Thanks,
//richard
More information about the libvir-list
mailing list