[libvirt] [PATCH v3 11/15] vircgroup: introduce virCgroupV2DenyDevice

Pavel Hrdina posted 15 patches 6 years, 9 months ago
[libvirt] [PATCH v3 11/15] vircgroup: introduce virCgroupV2DenyDevice
Posted by Pavel Hrdina 6 years, 9 months ago
In order to deny device we need to check if there is any entry in BPF
map and we need to load the current value from map if there is already
entry for that device.  If both values are same we can remove that entry
but if they are different we need to update the entry because we don't
have to deny all access, but for example only write access.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
 src/util/vircgroupv2.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
index 9f9802bb2f..bf78c33519 100644
--- a/src/util/vircgroupv2.c
+++ b/src/util/vircgroupv2.c
@@ -1668,6 +1668,46 @@ virCgroupV2AllowDevice(virCgroupPtr group,
 }
 
 
+static int
+virCgroupV2DenyDevice(virCgroupPtr group,
+                      char type,
+                      int major,
+                      int minor,
+                      int perms)
+{
+    uint64_t key = virCgroupV2DevicesGetKey(major, minor);
+    uint32_t newval = virCgroupV2DevicesGetPerms(perms, type);
+    uint32_t val = 0;
+
+    if (virCgroupV2DevicesPrepareProg(group) < 0)
+        return -1;
+
+    if (group->unified.devices.count <= 0 ||
+        virBPFLookupElem(group->unified.devices.mapfd, &key, &val) < 0) {
+        VIR_DEBUG("nothing to do, device is not allowed");
+        return 0;
+    }
+
+    if (newval == val) {
+        if (virBPFDeleteElem(group->unified.devices.mapfd, &key) < 0) {
+            virReportSystemError(errno, "%s",
+                                 _("failed to remove device from BPF cgroup map"));
+            return -1;
+        }
+        group->unified.devices.count--;
+    } else {
+        val ^= val & newval;
+        if (virBPFUpdateElem(group->unified.devices.mapfd, &key, &val) < 0) {
+            virReportSystemError(errno, "%s",
+                                 _("failed to update device in BPF cgroup map"));
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+
 virCgroupBackend virCgroupV2Backend = {
     .type = VIR_CGROUP_BACKEND_TYPE_V2,
 
@@ -1718,6 +1758,7 @@ virCgroupBackend virCgroupV2Backend = {
     .getMemSwapUsage = virCgroupV2GetMemSwapUsage,
 
     .allowDevice = virCgroupV2AllowDevice,
+    .denyDevice = virCgroupV2DenyDevice,
 
     .setCpuShares = virCgroupV2SetCpuShares,
     .getCpuShares = virCgroupV2GetCpuShares,
-- 
2.20.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 11/15] vircgroup: introduce virCgroupV2DenyDevice
Posted by Ján Tomko 6 years, 7 months ago
On Thu, Apr 25, 2019 at 09:44:28AM +0200, Pavel Hrdina wrote:
>In order to deny device we need to check if there is any entry in BPF
>map and we need to load the current value from map if there is already
>entry for that device.  If both values are same we can remove that entry
>but if they are different we need to update the entry because we don't
>have to deny all access, but for example only write access.
>
>Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
>---
> src/util/vircgroupv2.c | 41 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 41 insertions(+)
>

Reviewed-by: Ján Tomko <jtomko@redhat.com>

Jano
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list