chiark / gitweb /
util_run_program(): fix possible buffer overflow #2
[elogind.git] / udev / udevd.c
index 2cdc18b41e45a3a831d044a80d027e50dbd39d31..2eb914a3f335f61952b355328ef9c8fae707b559 100644 (file)
@@ -31,6 +31,7 @@
 #include <time.h>
 #include <getopt.h>
 #include <dirent.h>
+#include <sys/time.h>
 #include <sys/prctl.h>
 #include <sys/socket.h>
 #include <sys/signalfd.h>
@@ -53,8 +54,15 @@ static void log_fn(struct udev *udev, int priority,
                   const char *format, va_list args)
 {
        if (debug) {
-               fprintf(stderr, "[%d] %s: ", (int) getpid(), fn);
-               vfprintf(stderr, format, args);
+               char buf[1024];
+               struct timeval tv;
+               struct timezone tz;
+
+               vsnprintf(buf, sizeof(buf), format, args);
+               gettimeofday(&tv, &tz);
+               fprintf(stderr, "%llu.%06u [%u] %s: %s",
+                       (unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec,
+                       (int) getpid(), fn, buf);
        } else {
                vsyslog(priority, format, args);
        }
@@ -71,6 +79,7 @@ static bool stop_exec_queue;
 static bool reload_config;
 static int max_childs;
 static int childs;
+static sigset_t orig_sigmask;
 static struct udev_list_node event_list;
 static struct udev_list_node worker_list;
 static bool udev_exit;
@@ -157,7 +166,7 @@ static void event_queue_delete(struct event *event)
        udev_list_node_remove(&event->node);
 
        /* mark as failed, if "add" event returns non-zero */
-       if (event->exitcode && strcmp(udev_device_get_action(event->dev), "add") == 0)
+       if (event->exitcode != 0 && strcmp(udev_device_get_action(event->dev), "add") == 0)
                udev_queue_export_device_failed(udev_queue_export, event->dev);
        else
                udev_queue_export_device_finished(udev_queue_export, event->dev);
@@ -263,9 +272,11 @@ static void worker_new(struct event *event)
 
                do {
                        struct udev_event *udev_event;
-                       struct worker_message msg;
+                       struct worker_message msg = {};
                        int err;
+                       int failed = 0;
 
+                       info(event->udev, "seq %llu running\n", udev_device_get_seqnum(dev));
                        udev_event = udev_event_new(dev);
                        if (udev_event == NULL)
                                _exit(3);
@@ -282,7 +293,8 @@ static void worker_new(struct event *event)
 
                        /* execute RUN= */
                        if (err == 0 && !udev_event->ignore_device && udev_get_run(udev_event->udev))
-                               udev_event_execute_run(udev_event);
+                               failed = udev_event_execute_run(udev_event,
+                                                               &orig_sigmask);
 
                        /* reset alarm */
                        alarm(0);
@@ -297,7 +309,10 @@ static void worker_new(struct event *event)
                        udev_monitor_send_device(worker_monitor, NULL, dev);
 
                        /* send back the result of the event execution */
-                       msg.exitcode = err;
+                       if (err != 0)
+                               msg.exitcode = err;
+                       else if (failed != 0)
+                               msg.exitcode = failed;
                        msg.pid = getpid();
                        send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0);
 
@@ -763,7 +778,7 @@ static void startup_log(struct udev *udev)
                if (f != NULL)
                        fprintf(f, "<3>%s\n", depr_str);
                err(udev, "%s\n", depr_str);
-               sleep(3);
+               sleep(15);
        }
 
        if (f != NULL)
@@ -913,7 +928,7 @@ int main(int argc, char *argv[])
 
        /* block and listen to all signals on signalfd */
        sigfillset(&mask);
-       sigprocmask(SIG_SETMASK, &mask, NULL);
+       sigprocmask(SIG_SETMASK, &mask, &orig_sigmask);
        pfd[FD_SIGNAL].fd = signalfd(-1, &mask, 0);
        if (pfd[FD_SIGNAL].fd < 0) {
                fprintf(stderr, "error getting signalfd\n");