uinput: change strcpy/strcat usage for snprintf
authorPeter Hutterer <peter.hutterer@who-t.net>
Thu, 19 Jun 2014 04:20:58 +0000 (14:20 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Fri, 20 Jun 2014 01:00:16 +0000 (11:00 +1000)
Better protection against buffer overflow, though by the time someone
is manipulating your sysfs, libevdev is unlikely to be the biggest worry.

Slight change in functionality: before we checked the timestamp of
/sys/devices/virtual/input/inputXYZ before looking at /inputXYZ/name, now we
just check the name file for the timestamp.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
libevdev/libevdev-uinput.c

index f8607d18ebdc43541ba256c3dc211a877b0d7542..e8419e658c566b1e71bde9002c3fe36ab3a9e7fc 100644 (file)
@@ -218,8 +218,12 @@ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
                int fd, len;
                struct stat st;
 
-               strcpy(buf, SYS_INPUT_DIR);
-               strcat(buf, namelist[i]->d_name);
+               rc = snprintf(buf, sizeof(buf), "%s%s/name",
+                             SYS_INPUT_DIR,
+                             namelist[i]->d_name);
+               if (rc < 0 || (size_t)rc >= sizeof(buf)) {
+                       continue;
+               }
 
                if (stat(buf, &st) == -1)
                        continue;
@@ -230,7 +234,6 @@ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
                        continue;
 
                /* created within time frame */
-               strcat(buf, "/name");
                fd = open(buf, O_RDONLY);
                if (fd < 0)
                        continue;
@@ -247,8 +250,14 @@ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
                                log_info(NULL, "multiple identical devices found. syspath is unreliable\n");
                                break;
                        } else {
-                               strcpy(buf, SYS_INPUT_DIR);
-                               strcat(buf, namelist[i]->d_name);
+                               rc = snprintf(buf, sizeof(buf), "%s%s",
+                                             SYS_INPUT_DIR,
+                                             namelist[i]->d_name);
+                               if (rc < 0 || (size_t)rc >= sizeof(buf)) {
+                                       log_error(NULL, "Invalid syspath, syspath is unreliable\n");
+                                       break;
+                               }
+
                                uinput_dev->syspath = strdup(buf);
                                uinput_dev->devnode = fetch_device_node(buf);
                        }