]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: replace strtoul by safe_ato*
authorDavid Tardon <dtardon@redhat.com>
Tue, 22 Jun 2021 14:41:23 +0000 (16:41 +0200)
committerDavid Tardon <dtardon@redhat.com>
Thu, 24 Jun 2021 13:12:29 +0000 (15:12 +0200)
src/udev/scsi_id/scsi_id.c
src/udev/udev-builtin-input_id.c
src/udev/udev-builtin-keyboard.c
src/udev/udev-builtin-net_id.c
src/udev/udev-builtin-path_id.c
src/udev/udev-builtin-usb_id.c

index 41f92b68beaa1b4347c1c0d785d979e10b80fd2a..943262d4363f821c3e1e742e88ea0302881447c0 100644 (file)
@@ -12,7 +12,6 @@
 #include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
@@ -21,6 +20,7 @@
 #include "extract-word.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "parse-util.h"
 #include "scsi_id.h"
 #include "string-util.h"
 #include "strv.h"
@@ -58,12 +58,10 @@ static char revision_str[16];
 static char type_str[16];
 
 static void set_type(const char *from, char *to, size_t len) {
-        int type_num;
-        char *eptr;
+        unsigned type_num;
         const char *type = "generic";
 
-        type_num = strtoul(from, &eptr, 0);
-        if (eptr != from) {
+        if (safe_atou_full(from, 16, &type_num) >= 0) {
                 switch (type_num) {
                 case 0:
                         type = "disk";
index 2331525c87e67ad28d43a86e2d29cb10cab7b760..dda53b6da0f25dee7d73e8626bd66e0b30d9dc51 100644 (file)
@@ -9,7 +9,6 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
-#include <stdlib.h>
 #include <unistd.h>
 #include <linux/limits.h>
 
@@ -83,6 +82,7 @@ static void get_cap_mask(sd_device *pdev, const char* attr,
         unsigned i;
         char* word;
         unsigned long val;
+        int r;
 
         if (sd_device_get_sysattr_value(pdev, attr, &v) < 0)
                 v = "";
@@ -93,16 +93,20 @@ static void get_cap_mask(sd_device *pdev, const char* attr,
         memzero(bitmask, bitmask_size);
         i = 0;
         while ((word = strrchr(text, ' ')) != NULL) {
-                val = strtoul(word+1, NULL, 16);
-                if (i < bitmask_size / sizeof(unsigned long))
+                r = safe_atolu_full(word+1, 16, &val);
+                if (r < 0)
+                        log_device_debug_errno(pdev, r, "Ignoring %s block which failed to parse: %m", attr);
+                else if (i < bitmask_size / sizeof(unsigned long))
                         bitmask[i] = val;
                 else
                         log_device_debug(pdev, "Ignoring %s block %lX which is larger than maximum size", attr, val);
                 *word = '\0';
                 ++i;
         }
-        val = strtoul (text, NULL, 16);
-        if (i < bitmask_size / sizeof(unsigned long))
+        r = safe_atolu_full(text, 16, &val);
+        if (r < 0)
+                log_device_debug_errno(pdev, r, "Ignoring %s block which failed to parse: %m", attr);
+        else if (i < bitmask_size / sizeof(unsigned long))
                 bitmask[i] = val;
         else
                 log_device_debug(pdev, "Ignoring %s block %lX which is larger than maximum size", attr, val);
index cd766a8b6a5c76f0c2d7e358b2b50dfb66539cdc..a739e69e03f81d48551f73de7d4f592212b4987c 100644 (file)
@@ -60,9 +60,9 @@ static int map_keycode(sd_device *dev, int fd, int scancode, const char *keycode
                 unsigned scan;
                 unsigned key;
         } map;
-        char *endptr;
         const struct key_name *k;
         unsigned keycode_num;
+        int r;
 
         /* translate identifier to key code */
         k = keyboard_lookup_key(keycode, strlen(keycode));
@@ -70,9 +70,9 @@ static int map_keycode(sd_device *dev, int fd, int scancode, const char *keycode
                 keycode_num = k->id;
         } else {
                 /* check if it's a numeric code already */
-                keycode_num = strtoul(keycode, &endptr, 0);
-                if (endptr[0] !='\0')
-                        return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Failed to parse key identifier '%s'", keycode);
+                r = safe_atou(keycode, &keycode_num);
+                if (r < 0)
+                        return log_device_error_errno(dev, r, "Failed to parse key identifier '%s': %m", keycode);
         }
 
         map.scan = scancode;
@@ -170,17 +170,15 @@ static int builtin_keyboard(sd_device *dev, int argc, char *argv[], bool test) {
         if (r < 0)
                 return log_device_error_errno(dev, r, "Failed to get device name: %m");
 
-        FOREACH_DEVICE_PROPERTY(dev, key, value) {
-                char *endptr;
-
+        FOREACH_DEVICE_PROPERTY(dev, key, value)
                 if (startswith(key, "KEYBOARD_KEY_")) {
                         const char *keycode = value;
                         unsigned scancode;
 
                         /* KEYBOARD_KEY_<hex scan code>=<key identifier string> */
-                        scancode = strtoul(key + 13, &endptr, 16);
-                        if (endptr[0] != '\0') {
-                                log_device_warning(dev, "Failed to parse scan code from \"%s\", ignoring", key);
+                        r = safe_atou_full(key + 13, 16, &scancode);
+                        if (r < 0) {
+                                log_device_warning_errno(dev, r, "Failed to parse scan code from \"%s\", ignoring: %m", key);
                                 continue;
                         }
 
@@ -207,9 +205,9 @@ static int builtin_keyboard(sd_device *dev, int argc, char *argv[], bool test) {
                         unsigned evcode;
 
                         /* EVDEV_ABS_<EV_ABS code>=<min>:<max>:<res>:<fuzz>:<flat> */
-                        evcode = strtoul(key + 10, &endptr, 16);
-                        if (endptr[0] != '\0') {
-                                log_device_warning(dev, "Failed to parse EV_ABS code from \"%s\", ignoring", key);
+                        r = safe_atou_full(key + 10, 16, &evcode);
+                        if (r < 0) {
+                                log_device_warning_errno(dev, r, "Failed to parse EV_ABS code from \"%s\", ignoring: %m", key);
                                 continue;
                         }
 
@@ -238,7 +236,6 @@ static int builtin_keyboard(sd_device *dev, int argc, char *argv[], bool test) {
                         (void) override_abs(dev, fd, evcode, value);
                 } else if (streq(key, "POINTINGSTICK_SENSITIVITY"))
                         (void) set_trackpoint_sensitivity(dev, value);
-        }
 
         /* install list of force-release codes */
         if (release_count > 0)
index 33601151a6fc3a931490b4d8d2bc2f5d2dfeec9c..92917852ba6b95053a95d42a0dbb28963b7e80d7 100644 (file)
@@ -17,7 +17,6 @@
 #include <net/if.h>
 #include <net/if_arp.h>
 #include <stdarg.h>
-#include <stdlib.h>
 #include <unistd.h>
 #include <linux/if.h>
 #include <linux/pci_regs.h>
@@ -199,8 +198,11 @@ static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
                 return -ENOENT;
 
         /* kernel provided port index for multiple ports on a single PCI function */
-        if (sd_device_get_sysattr_value(dev, "dev_port", &attr) >= 0)
-                dev_port = strtoul(attr, NULL, 10);
+        if (sd_device_get_sysattr_value(dev, "dev_port", &attr) >= 0) {
+                r = safe_atolu_full(attr, 10, &dev_port);
+                if (r < 0)
+                        log_device_debug_errno(dev, r, "Failed to parse dev_port, ignoring: %m");
+        }
 
         /* kernel provided front panel port name for multiple port PCI device */
         (void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name);
@@ -341,7 +343,9 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
 
         /* kernel provided port index for multiple ports on a single PCI function */
         if (sd_device_get_sysattr_value(dev, "dev_port", &attr) >= 0) {
-                dev_port = strtoul(attr, NULL, 10);
+                r = safe_atolu_full(attr, 10, &dev_port);
+                if (r < 0)
+                        log_device_debug_errno(dev, r, "Failed to parse attribute dev_port, ignoring: %m");
                 /* With older kernels IP-over-InfiniBand network interfaces sometimes erroneously
                  * provide the port number in the 'dev_id' sysfs attribute instead of 'dev_port',
                  * which thus stays initialized as 0. */
@@ -349,10 +353,15 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
                     sd_device_get_sysattr_value(dev, "type", &attr) >= 0) {
                         unsigned long type;
 
-                        type = strtoul(attr, NULL, 10);
-                        if (type == ARPHRD_INFINIBAND &&
-                            sd_device_get_sysattr_value(dev, "dev_id", &attr) >= 0)
-                                dev_port = strtoul(attr, NULL, 16);
+                        r = safe_atolu_full(attr, 10, &type);
+                        if (r < 0)
+                                log_device_debug_errno(dev, r, "Failed to parse attribute type, ignoring: %m");
+                        else if (type == ARPHRD_INFINIBAND &&
+                                 sd_device_get_sysattr_value(dev, "dev_id", &attr) >= 0) {
+                                r = safe_atolu_full(attr, 10, &dev_port);
+                                if (r < 0)
+                                        log_device_debug_errno(dev, r, "Failed to parse attribute dev_id, ignoring: %m");
+                        }
                 }
         }
 
@@ -765,7 +774,9 @@ static int names_mac(sd_device *dev, struct netnames *names) {
         if (r < 0)
                 return r;
 
-        i = strtoul(s, NULL, 0);
+        r = safe_atolu_full(s, 10, &i);
+        if (r < 0)
+                return r;
         switch (i) {
         /* The persistent part of a hardware address of an InfiniBand NIC
          * is 8 bytes long. We cannot fit this much in an iface name.
@@ -780,7 +791,9 @@ static int names_mac(sd_device *dev, struct netnames *names) {
         r = sd_device_get_sysattr_value(dev, "addr_assign_type", &s);
         if (r < 0)
                 return r;
-        i = strtoul(s, NULL, 0);
+        r = safe_atolu(s, &i);
+        if (r < 0)
+                return r;
         if (i != 0)
                 return 0;
 
@@ -868,7 +881,9 @@ static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) {
         if (r < 0)
                 return r;
 
-        i = strtoul(s, NULL, 0);
+        r = safe_atolu_full(s, 10, &i);
+        if (r < 0)
+                return r;
         switch (i) {
         case ARPHRD_ETHER:
                 prefix = "en";
index 5e7945081e6f44a5f650c1f6f4449a34cbfa2362..65c40de4c8cb4721d946bbee948110ece25ffdc5 100644 (file)
 #include <getopt.h>
 #include <stdarg.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <unistd.h>
 
 #include "alloc-util.h"
 #include "dirent-util.h"
 #include "fd-util.h"
+#include "parse-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "sysexits.h"
@@ -66,7 +66,9 @@ static int format_lun_number(sd_device *dev, char **path) {
         if (!sysnum)
                 return -ENOENT;
 
-        lun = strtoul(sysnum, NULL, 10);
+        r = safe_atolu_full(sysnum, 10, &lun);
+        if (r < 0)
+                return r;
         if (lun < 256)
                 /* address method 0, peripheral device addressing with bus id of zero */
                 path_prepend(path, "lun-%lu", lun);
@@ -344,8 +346,7 @@ static sd_device *handle_scsi_default(sd_device *parent, char **path) {
                 return NULL;
 
         FOREACH_DIRENT_ALL(dent, dir, break) {
-                char *rest;
-                int i;
+                unsigned i;
 
                 if (dent->d_name[0] == '.')
                         continue;
@@ -353,15 +354,14 @@ static sd_device *handle_scsi_default(sd_device *parent, char **path) {
                         continue;
                 if (!startswith(dent->d_name, "host"))
                         continue;
-                i = strtoul(&dent->d_name[4], &rest, 10);
-                if (rest[0] != '\0')
+                if (safe_atou_full(&dent->d_name[4], 10, &i) < 0)
                         continue;
                 /*
                  * find the smallest number; the host really needs to export its
                  * own instance number per parent device; relying on the global host
                  * enumeration and plainly rebasing the numbers sounds unreliable
                  */
-                if (basenum == -1 || i < basenum)
+                if (basenum == -1 || (int) i < basenum)
                         basenum = i;
         }
         if (basenum == -1)
index 7d94c6b0a38a4bb9355eff10d97c467f888eed68..bdaecb812b02b4032b9d25c55eb44fbbc559703f 100644 (file)
 #include <fcntl.h>
 #include <stdarg.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <unistd.h>
 
 #include "alloc-util.h"
 #include "device-nodes.h"
 #include "device-util.h"
 #include "fd-util.h"
+#include "parse-util.h"
 #include "string-util.h"
 #include "strxcpyx.h"
 #include "udev-builtin.h"
@@ -75,11 +75,9 @@ static void set_usb_iftype(char *to, int if_class_num, size_t len) {
 
 static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len) {
         int type_num = 0;
-        char *eptr;
         const char *type = "generic";
 
-        type_num = strtoul(from, &eptr, 0);
-        if (eptr != from) {
+        if (safe_atoi(from, &type_num) >= 0) {
                 switch (type_num) {
                 case 1: /* RBC devices */
                         type = "rbc";
@@ -105,12 +103,10 @@ static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len
 }
 
 static void set_scsi_type(char *to, const char *from, size_t len) {
-        int type_num;
-        char *eptr;
+        unsigned type_num;
         const char *type = "generic";
 
-        type_num = strtoul(from, &eptr, 0);
-        if (eptr != from) {
+        if (safe_atou(from, &type_num) >= 0) {
                 switch (type_num) {
                 case 0:
                 case 0xe:
@@ -246,7 +242,7 @@ static int builtin_usb_id(sd_device *dev, int argc, char *argv[], bool test) {
 
         sd_device *dev_interface, *dev_usb;
         const char *if_class, *if_subclass;
-        int if_class_num;
+        unsigned if_class_num;
         int protocol = 0;
         size_t l;
         char *s;
@@ -286,7 +282,9 @@ static int builtin_usb_id(sd_device *dev, int argc, char *argv[], bool test) {
         if (r < 0)
                 return log_device_debug_errno(dev_interface, r, "Failed to get bInterfaceClass attribute: %m");
 
-        if_class_num = strtoul(if_class, NULL, 16);
+        r = safe_atou_full(if_class, 16, &if_class_num);
+        if (r < 0)
+                return log_device_debug_errno(dev_interface, r, "Failed to parse if_class: %m");
         if (if_class_num == 8) {
                 /* mass storage */
                 if (sd_device_get_sysattr_value(dev_interface, "bInterfaceSubClass", &if_subclass) >= 0)