]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
libudev: add missing errno initialization/error propagation (#6781)
authorLennart Poettering <lennart@poettering.net>
Sat, 9 Sep 2017 20:31:09 +0000 (22:31 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 9 Sep 2017 20:31:09 +0000 (22:31 +0200)
In libudev (which es much older code than the rest of systemd), we
propagate errors in functions not returning an int, via (positive) errno
(i.e. libc-style), and as negative Exyz values in those returning an int
(much preferred, i.e. Linux kernel style). Let's fix up a few place,
where this was incorrectly done, or not done at all.

Fixes: #6613
src/libudev/libudev-enumerate.c
src/libudev/libudev-hwdb.c
src/libudev/libudev-monitor.c
src/libudev/libudev-queue.c
src/libudev/libudev.c

index 3b8abfb2607ba4ead4a0991b684689f8bb8cec7d..ea80c750c91a9e9ae67d1207b8104b6a45af9884 100644 (file)
@@ -159,6 +159,8 @@ _public_ struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumer
  * Returns: a udev_list_entry.
  */
 _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate) {
+        struct udev_list_entry *e;
+
         assert_return_errno(udev_enumerate, NULL, EINVAL);
 
         if (!udev_enumerate->devices_uptodate) {
@@ -182,7 +184,11 @@ _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enume
                 udev_enumerate->devices_uptodate = true;
         }
 
-        return udev_list_get_entry(&udev_enumerate->devices_list);
+        e = udev_list_get_entry(&udev_enumerate->devices_list);
+        if (!e)
+                errno = ENODATA;
+
+        return e;
 }
 
 /**
index a53f000015468046157d84dd6f7f5ab72424b18a..4bdc37d973a4cb9a927118b8760945cd3347e6e8 100644 (file)
@@ -57,15 +57,19 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
         struct udev_hwdb *hwdb;
         int r;
 
-        assert_return(udev, NULL);
+        assert_return_errno(udev, NULL, EINVAL);
 
         r = sd_hwdb_new(&hwdb_internal);
-        if (r < 0)
+        if (r < 0) {
+                errno = -r;
                 return NULL;
+        }
 
         hwdb = new0(struct udev_hwdb, 1);
-        if (!hwdb)
+        if (!hwdb) {
+                errno = ENOMEM;
                 return NULL;
+        }
 
         hwdb->refcount = 1;
         hwdb->hwdb = hwdb_internal;
@@ -127,6 +131,7 @@ _public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
  */
 _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) {
         const char *key, *value;
+        struct udev_list_entry *e;
 
         if (!hwdb || !modalias) {
                 errno = EINVAL;
@@ -142,5 +147,9 @@ _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev
                 }
         }
 
-        return udev_list_get_entry(&hwdb->properties_list);
+        e = udev_list_get_entry(&hwdb->properties_list);
+        if (!e)
+                errno = ENODATA;
+
+        return e;
 }
index 8287694c498637cafe4cc1f6cbed7c926375046d..32f2154b3622766789677205c8261bc6639fa767 100644 (file)
@@ -100,8 +100,10 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev)
         struct udev_monitor *udev_monitor;
 
         udev_monitor = new0(struct udev_monitor, 1);
-        if (udev_monitor == NULL)
+        if (udev_monitor == NULL) {
+                errno = ENOMEM;
                 return NULL;
+        }
         udev_monitor->refcount = 1;
         udev_monitor->udev = udev;
         udev_list_init(udev, &udev_monitor->filter_subsystem_list, false);
@@ -171,8 +173,10 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
         struct udev_monitor *udev_monitor;
         unsigned int group;
 
-        if (udev == NULL)
+        if (udev == NULL) {
+                errno = EINVAL;
                 return NULL;
+        }
 
         if (name == NULL)
                 group = UDEV_MONITOR_NONE;
@@ -196,8 +200,10 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
                         group = UDEV_MONITOR_UDEV;
         } else if (streq(name, "kernel"))
                 group = UDEV_MONITOR_KERNEL;
-        else
+        else {
+                errno = EINVAL;
                 return NULL;
+        }
 
         udev_monitor = udev_monitor_new(udev);
         if (udev_monitor == NULL)
@@ -438,7 +444,10 @@ _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_moni
 {
         if (udev_monitor == NULL)
                 return -EINVAL;
-        return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size));
+        if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size)) < 0)
+                return -errno;
+
+        return 0;
 }
 
 int udev_monitor_disconnect(struct udev_monitor *udev_monitor)
@@ -596,8 +605,10 @@ _public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *ud
         bool is_initialized = false;
 
 retry:
-        if (udev_monitor == NULL)
+        if (udev_monitor == NULL) {
+                errno = EINVAL;
                 return NULL;
+        }
         iov.iov_base = &buf;
         iov.iov_len = sizeof(buf);
         memzero(&smsg, sizeof(struct msghdr));
@@ -617,6 +628,7 @@ retry:
 
         if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC)) {
                 log_debug("invalid message length");
+                errno = EINVAL;
                 return NULL;
         }
 
@@ -625,12 +637,14 @@ retry:
                 if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 ||
                     snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) {
                         log_debug("unicast netlink message ignored");
+                        errno = EAGAIN;
                         return NULL;
                 }
         } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) {
                 if (snl.nl.nl_pid > 0) {
                         log_debug("multicast kernel netlink message from PID %"PRIu32" ignored",
                                   snl.nl.nl_pid);
+                        errno = EAGAIN;
                         return NULL;
                 }
         }
@@ -638,12 +652,14 @@ retry:
         cmsg = CMSG_FIRSTHDR(&smsg);
         if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
                 log_debug("no sender credentials received, message ignored");
+                errno = EAGAIN;
                 return NULL;
         }
 
         cred = (struct ucred *)CMSG_DATA(cmsg);
         if (cred->uid != 0) {
                 log_debug("sender uid="UID_FMT", message ignored", cred->uid);
+                errno = EAGAIN;
                 return NULL;
         }
 
@@ -652,11 +668,13 @@ retry:
                 if (buf.nlh.magic != htobe32(UDEV_MONITOR_MAGIC)) {
                         log_debug("unrecognized message signature (%x != %x)",
                                  buf.nlh.magic, htobe32(UDEV_MONITOR_MAGIC));
+                        errno = EAGAIN;
                         return NULL;
                 }
                 if (buf.nlh.properties_off+32 > (size_t)buflen) {
                         log_debug("message smaller than expected (%u > %zd)",
                                   buf.nlh.properties_off+32, buflen);
+                        errno = EAGAIN;
                         return NULL;
                 }
 
@@ -669,12 +687,14 @@ retry:
                 bufpos = strlen(buf.raw) + 1;
                 if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) {
                         log_debug("invalid message length");
+                        errno = EAGAIN;
                         return NULL;
                 }
 
                 /* check message header */
                 if (strstr(buf.raw, "@/") == NULL) {
                         log_debug("unrecognized message header");
+                        errno = EAGAIN;
                         return NULL;
                 }
         }
@@ -701,6 +721,8 @@ retry:
                 rc = poll(pfd, 1, 0);
                 if (rc > 0)
                         goto retry;
+
+                errno = EAGAIN;
                 return NULL;
         }
 
@@ -837,8 +859,11 @@ _public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor
  */
 _public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor)
 {
-        static struct sock_fprog filter = { 0, NULL };
+        static const struct sock_fprog filter = { 0, NULL };
 
         udev_list_cleanup(&udev_monitor->filter_subsystem_list);
-        return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
+        if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0)
+                return -errno;
+
+        return 0;
 }
index e3dffa6925fe0aba3b478445bd83dfcdeaa500a7..f3143d46150bbf9cb835b87f9beb5d6def87c0ea 100644 (file)
@@ -60,12 +60,16 @@ _public_ struct udev_queue *udev_queue_new(struct udev *udev)
 {
         struct udev_queue *udev_queue;
 
-        if (udev == NULL)
+        if (udev == NULL) {
+                errno = EINVAL;
                 return NULL;
+        }
 
         udev_queue = new0(struct udev_queue, 1);
-        if (udev_queue == NULL)
+        if (udev_queue == NULL) {
+                errno = ENOMEM;
                 return NULL;
+        }
 
         udev_queue->refcount = 1;
         udev_queue->udev = udev;
@@ -124,8 +128,10 @@ _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue)
  **/
 _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue)
 {
-        if (udev_queue == NULL)
+        if (udev_queue == NULL) {
+                errno = EINVAL;
                 return NULL;
+        }
         return udev_queue->udev;
 }
 
@@ -223,6 +229,7 @@ _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, un
  **/
 _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue)
 {
+        errno = ENODATA;
         return NULL;
 }
 
index d7b82a758f387766dc18bf637d6b398d868e419a..ce8d5b5760580f61f7f1884ec55a02d0f116b565 100644 (file)
@@ -97,7 +97,7 @@ _public_ struct udev *udev_new(void) {
 
         udev = new0(struct udev, 1);
         if (!udev) {
-                errno = -ENOMEM;
+                errno = ENOMEM;
                 return NULL;
         }
         udev->refcount = 1;