]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
commands: only update bpf device program if really needed
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 19 Feb 2021 03:03:09 +0000 (04:03 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 19 Feb 2021 14:23:26 +0000 (15:23 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/cgroups/cgroup2_devices.c
src/lxc/cgroups/cgroup2_devices.h

index 5fb9ff66cb0f0654cc0d657d4723b848ac503730..e264dca25b0376cddfaee8429287ad783dc0b041 100644 (file)
@@ -3095,6 +3095,11 @@ static int bpf_device_cgroup_prepare(struct cgroup_ops *ops,
        if (ret < 0)
                return log_error_errno(-1, EINVAL, "Failed to parse device string %s=%s", key, val);
 
+       /*
+        * Note that bpf_list_add_device() indicates whether or not it had to
+        * alter the current device list by return 1 and 0; both indicate
+        * success. A negative return value indicates and error.
+        */
        ret = bpf_list_add_device(&conf->bpf_devices, &device_item);
        if (ret < 0)
                return -1;
index f1442de31bf2c4776d9f0ce3da0e552e44a921bf..0fe99ce5816cca07f1db079cf2515799bf1f5cfc 100644 (file)
@@ -433,6 +433,7 @@ void bpf_device_program_free(struct cgroup_ops *ops)
 int bpf_list_add_device(struct bpf_devices *bpf_devices,
                        struct device_item *device)
 {
+       int device_list_altered = 0;
        __do_free struct lxc_list *list_elem = NULL;
        __do_free struct device_item *new_device = NULL;
        struct lxc_list *it;
@@ -446,14 +447,22 @@ int bpf_list_add_device(struct bpf_devices *bpf_devices,
            device->minor < 0 &&
            is_empty_string(device->access)) {
                if (device->allow) {
-                       bpf_devices->list_type = LXC_BPF_DEVICE_CGROUP_DENYLIST;
+                       if (bpf_devices->list_type != LXC_BPF_DEVICE_CGROUP_DENYLIST) {
+                               bpf_devices->list_type = LXC_BPF_DEVICE_CGROUP_DENYLIST;
+                               device_list_altered = 1;
+                       }
+
                        TRACE("Device cgroup will allow (\"denylist\") all devices by default");
                } else {
-                       bpf_devices->list_type = LXC_BPF_DEVICE_CGROUP_ALLOWLIST;
-                       TRACE("Device cgroup will deny (\"allowlist\") all devices by default");
+                       if (bpf_devices->list_type != LXC_BPF_DEVICE_CGROUP_ALLOWLIST) {
+                               bpf_devices->list_type = LXC_BPF_DEVICE_CGROUP_ALLOWLIST;
+                               device_list_altered = 1;
+                       }
+
+                       TRACE("Device cgroup will block (\"allowlist\") all devices by default");
                }
 
-               return 0;
+               return device_list_altered;
        }
 
        lxc_list_for_each(it, &bpf_devices->device_item) {
@@ -474,6 +483,8 @@ int bpf_list_add_device(struct bpf_devices *bpf_devices,
                 */
                if (cur->allow != device->allow) {
                        cur->allow = device->allow;
+                       device_list_altered = 1;
+
                        TRACE("Switched existing rule: type %c, major %d, minor %d, access %s, allow %d",
                              cur->type, cur->major, cur->minor, cur->access, cur->allow);
                } else {
@@ -481,9 +492,10 @@ int bpf_list_add_device(struct bpf_devices *bpf_devices,
                              cur->type, cur->major, cur->minor, cur->access, cur->allow);
                }
 
-               return 0;
+               return device_list_altered;
        }
 
+       device_list_altered = 1;
        list_elem = malloc(sizeof(*list_elem));
        if (!list_elem)
                return syserrno_set(ENOMEM, "Failed to allocate new device list");
@@ -495,7 +507,7 @@ int bpf_list_add_device(struct bpf_devices *bpf_devices,
        lxc_list_add_elem(list_elem, move_ptr(new_device));
        lxc_list_add_tail(&bpf_devices->device_item, move_ptr(list_elem));
 
-       return 0;
+       return device_list_altered;
 }
 
 bool bpf_devices_cgroup_supported(void)
@@ -626,10 +638,18 @@ bool bpf_cgroup_devices_update(struct cgroup_ops *ops,
        if (ops->unified->cgfd_limit < 0)
                return ret_set_errno(false, EBADF);
 
+       /*
+        * Note that bpf_list_add_device() indicates whether or not it had to
+        * alter the current device list by return 1 and 0; both indicate
+        * success. A negative return value indicates and error.
+        */
        ret = bpf_list_add_device(bpf_devices, new);
        if (ret < 0)
                return false;
 
+       if (ret == 0)
+               return log_trace(true, "Device bpf program unaltered");
+
        /* No previous device program attached. */
        prog_old = ops->cgroup2_devices;
        if (!prog_old)
index d1de5794f973e132cd0957fe0987a173f2014126..e920992b5fa0b7a0d25f00d9913d9f5c28087b49 100644 (file)
@@ -62,6 +62,11 @@ __hidden extern int bpf_program_cgroup_detach(struct bpf_program *prog);
 __hidden extern void bpf_device_program_free(struct cgroup_ops *ops);
 __hidden extern bool bpf_devices_cgroup_supported(void);
 
+/*
+ * Note that bpf_list_add_device() indicates whether or not it had to alter the
+ * current device list by return 1 and 0; both indicate success. A negative
+ * return value indicates and error.
+ */
 __hidden extern int bpf_list_add_device(struct bpf_devices *bpf_devices,
                                        struct device_item *device);
 __hidden extern bool bpf_cgroup_devices_attach(struct cgroup_ops *ops,