]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: destroy manager before cleaning environment 463/head
authorDavid Herrmann <dh.herrmann@gmail.com>
Wed, 1 Jul 2015 17:25:30 +0000 (19:25 +0200)
committerDavid Herrmann <dh.herrmann@gmail.com>
Wed, 1 Jul 2015 17:30:24 +0000 (19:30 +0200)
Due to our _cleanup_ usage for the udev manager, it will be destroyed
after the "exit:" label has finished. Therefore, it is the last
destruction done in main(). This has two side-effects:
  - mac_selinux is destroyed before the udev manager is, possible causing
    use-after-free if the manager-cleanup accesses selinux data
  - log_close() is called *before* the manager is destroyed, possibly
    re-opening the log if you use --debug (and thus not re-applying the
    --debug option)

Avoid this by moving the manager-handling into a new function called
run(). This function will be left before we enter the "exit:" label in
main(), hence, the manager object will be destroyed early.

src/udev/udevd.c

index cf15ddf641a5d388f1c5b2689b616860b02a91be..0b05913a7863ac4f647483f62ffe22caa141bdb5 100644 (file)
@@ -1608,8 +1608,42 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
         return 0;
 }
 
-int main(int argc, char *argv[]) {
+static int run(int fd_ctrl, int fd_uevent, const char *cgroup) {
         _cleanup_(manager_freep) Manager *manager = NULL;
+        int r;
+
+        r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup);
+        if (r < 0) {
+                r = log_error_errno(r, "failed to allocate manager object: %m");
+                goto exit;
+        }
+
+        r = udev_rules_apply_static_dev_perms(manager->rules);
+        if (r < 0)
+                log_error_errno(r, "failed to apply permissions on static device nodes: %m");
+
+        (void) sd_notify(false,
+                         "READY=1\n"
+                         "STATUS=Processing...");
+
+        r = sd_event_loop(manager->event);
+        if (r < 0) {
+                log_error_errno(r, "event loop failed: %m");
+                goto exit;
+        }
+
+        sd_event_get_exit_code(manager->event, &r);
+
+exit:
+        sd_notify(false,
+                  "STOPPING=1\n"
+                  "STATUS=Shutting down...");
+        if (manager)
+                udev_ctrl_cleanup(manager->ctrl);
+        return r;
+}
+
+int main(int argc, char *argv[]) {
         _cleanup_free_ char *cgroup = NULL;
         int r, fd_ctrl, fd_uevent;
 
@@ -1714,35 +1748,9 @@ int main(int argc, char *argv[]) {
                 write_string_file("/proc/self/oom_score_adj", "-1000");
         }
 
-        r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup);
-        if (r < 0) {
-                r = log_error_errno(r, "failed to allocate manager object: %m");
-                goto exit;
-        }
-
-        r = udev_rules_apply_static_dev_perms(manager->rules);
-        if (r < 0)
-                log_error_errno(r, "failed to apply permissions on static device nodes: %m");
-
-        (void) sd_notify(false,
-                         "READY=1\n"
-                         "STATUS=Processing...");
-
-        r = sd_event_loop(manager->event);
-        if (r < 0) {
-                log_error_errno(r, "event loop failed: %m");
-                goto exit;
-        }
-
-        sd_event_get_exit_code(manager->event, &r);
+        r = run(fd_ctrl, fd_uevent, cgroup);
 
 exit:
-        sd_notify(false,
-                  "STOPPING=1\n"
-                  "STATUS=Shutting down...");
-
-        if (manager)
-                udev_ctrl_cleanup(manager->ctrl);
         mac_selinux_finish();
         log_close();
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;