diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2014-06-19 14:20:58 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2014-06-20 11:00:16 +1000 |
commit | 734aadb4871c6190328fc70f88931fe896df4de5 (patch) | |
tree | 24b8dac5241e352dfada511efb9b9e1a6b7eafb4 | |
parent | 2ff45c73a1ce5577a4a06cf255a394d3c93d0915 (diff) | |
download | libevdev-734aadb4871c6190328fc70f88931fe896df4de5.tar.gz |
uinput: change strcpy/strcat usage for snprintf
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>
-rw-r--r-- | libevdev/libevdev-uinput.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/libevdev/libevdev-uinput.c b/libevdev/libevdev-uinput.c index f8607d1..e8419e6 100644 --- a/libevdev/libevdev-uinput.c +++ b/libevdev/libevdev-uinput.c @@ -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); } |