(backport) udev/net-id: check all snprintf return values
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 23 Feb 2018 10:12:19 +0000 (11:12 +0100)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Mon, 12 Feb 2024 15:37:44 +0000 (16:37 +0100)
gcc-8 throws an error if it knows snprintf might truncate output and the
return value is ignored:
../src/udev/udev-builtin-net_id.c: In function 'dev_pci_slot':
../src/udev/udev-builtin-net_id.c:297:47: error: '%s' directive output may be truncated writing up to 255 bytes into a region of size between 0 and 4095 [-Werror=format-truncation=]
                 snprintf(str, sizeof str, "%s/%s/address", slots, dent->d_name);
                                               ^~
../src/udev/udev-builtin-net_id.c:297:17: note: 'snprintf' output between 10 and 4360 bytes into a destination of size 4096
                 snprintf(str, sizeof str, "%s/%s/address", slots, dent->d_name);
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors

Let's check all return values. This actually makes the code better, because there's
no point in trying to open a file when the name has been truncated, etc.

Change-Id: I52c289a5e4d660c999383ee628c596e00c30af21

src/basic/stdio-util.h
src/udev/udev-builtin-net_id.c

index bd1144b..c594010 100644 (file)
 
 #include "macro.h"
 
-#define xsprintf(buf, fmt, ...) \
-        assert_message_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf), "xsprintf: " #buf "[] must be big enough")
+#define snprintf_ok(buf, len, fmt, ...) \
+        ((size_t) snprintf(buf, len, fmt, __VA_ARGS__) < (len))
 
+#define xsprintf(buf, fmt, ...) \
+        assert_message_se(snprintf_ok(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__), "xsprintf: " #buf "[] must be big enough")
 
 #define VA_FORMAT_ADVANCE(format, ap)                                   \
 do {                                                                    \
index 46eb611..bc408e8 100644 (file)
@@ -274,7 +274,9 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
                 goto out;
         }
 
-        snprintf(slots, sizeof slots, "%s/slots", udev_device_get_syspath(pci));
+        if (!snprintf_ok(slots, sizeof slots, "%s/slots", udev_device_get_syspath(pci)))
+                return -ENAMETOOLONG;
+
         dir = opendir(slots);
         if (!dir) {
                 err = -errno;
@@ -293,10 +295,10 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
                 if (i < 1)
                         continue;
 
-                snprintf(str, sizeof str, "%s/%s/address", slots, dent->d_name);
-                if (read_one_line_file(str, &address) >= 0) {
+                if (snprintf_ok(str, sizeof str, "%s/%s/address", slots, dent->d_name) &&
+                    read_one_line_file(str, &address) >= 0) {
                         /* match slot address with device by stripping the function */
-                        if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
+                        if (streq(address, udev_device_get_sysname(names->pcidev)))
                                 hotplug_slot = i;
                         free(address);
                 }
@@ -516,7 +518,6 @@ static int names_ccw(struct  udev_device *dev, struct netnames *names) {
         const char *bus_id, *subsys;
         size_t bus_id_len;
         size_t bus_id_start;
-        int rc;
 
         assert(dev);
         assert(names);
@@ -558,9 +559,9 @@ static int names_ccw(struct  udev_device *dev, struct netnames *names) {
         bus_id += bus_id_start < bus_id_len ? bus_id_start : bus_id_len - 1;
 
         /* Store the CCW bus-ID for use as network device name */
-        rc = snprintf(names->ccw_busid, sizeof(names->ccw_busid), "c%s", bus_id);
-        if (rc >= 0 && rc < (int)sizeof(names->ccw_busid))
+        if (snprintf_ok(names->ccw_busid, sizeof(names->ccw_busid), "c%s", bus_id))
                 names->type = NET_CCW;
+
         return 0;
 }
 
@@ -673,7 +674,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         if (err >= 0 && names.type == NET_CCW) {
                 char str[IFNAMSIZ];
 
-                if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_busid) < (int)sizeof(str))
+                if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.ccw_busid))
                         udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
                 goto out;
         }
@@ -683,7 +684,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         if (err >= 0 && names.type == NET_VIO) {
                 char str[IFNAMSIZ];
 
-                if (snprintf(str, sizeof(str), "%s%s", prefix, names.vio_slot) < (int)sizeof(str))
+                if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.vio_slot))
                         udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
                 goto out;
         }
@@ -693,7 +694,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         if (err >= 0 && names.type == NET_PLATFORM) {
                 char str[IFNAMSIZ];
 
-                if (snprintf(str, sizeof(str), "%s%s", prefix, names.platform_path) < (int)sizeof(str))
+                if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.platform_path))
                         udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
                 goto out;
         }
@@ -707,21 +708,21 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         if (names.type == NET_PCI) {
                 char str[IFNAMSIZ];
 
-                if (names.pci_onboard[0])
-                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str);
+                if (names.pci_onboard[0] &&
+                    snprintf_ok(str, sizeof str, "%s%s", prefix, names.pci_onboard))
+                        udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str);
 
-                if (names.pci_onboard_label)
-                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard_label) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str);
+                if (names.pci_onboard_label &&
+                    snprintf_ok(str, sizeof str, "%s%s", prefix, names.pci_onboard_label))
+                        udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str);
 
-                if (names.pci_path[0])
-                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_path) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
+                if (names.pci_path[0] &&
+                    snprintf_ok(str, sizeof str, "%s%s", prefix, names.pci_path))
+                        udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
 
-                if (names.pci_slot[0])
-                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_slot) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+                if (names.pci_slot[0] &&
+                    snprintf_ok(str, sizeof str, "%s%s", prefix, names.pci_slot))
+                        udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
                 goto out;
         }
 
@@ -730,13 +731,13 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         if (err >= 0 && names.type == NET_USB) {
                 char str[IFNAMSIZ];
 
-                if (names.pci_path[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.usb_ports) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
+                if (names.pci_path[0] &&
+                    snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_path, names.usb_ports))
+                        udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
 
-                if (names.pci_slot[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+                if (names.pci_slot[0] &&
+                    snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_slot, names.usb_ports))
+                        udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
                 goto out;
         }
 
@@ -745,13 +746,13 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         if (err >= 0 && names.type == NET_BCMA) {
                 char str[IFNAMSIZ];
 
-                if (names.pci_path[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.bcma_core) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
+                if (names.pci_path[0] &&
+                    snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_path, names.bcma_core))
+                        udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
 
-                if (names.pci_slot[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.bcma_core) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+                if (names.pci_slot[0] &&
+                    snprintf(str, sizeof str, "%s%s%s", prefix, names.pci_slot, names.bcma_core))
+                        udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
                 goto out;
         }
 out: