From 60067cc75ac7dd583beea584f87f2f6d3358f3c1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 21 Apr 2010 14:44:33 +0200 Subject: [PATCH] more readlink buffer size handling --- libudev/libudev-device.c | 27 ++++++++++++++------------- libudev/libudev-queue.c | 2 +- udev/udev-node.c | 4 ++-- udev/udev-watch.c | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/libudev/libudev-device.c b/libudev/libudev-device.c index b3b6a631..40035453 100644 --- a/libudev/libudev-device.c +++ b/libudev/libudev-device.c @@ -222,12 +222,11 @@ int udev_device_read_db(struct udev_device *udev_device) char *next; target_len = readlink(filename, target, sizeof(target)); - if (target_len > 0) - target[target_len] = '\0'; - else { - dbg(udev_device->udev, "error reading db link %s: %m\n", filename); + if (target_len <= 0 || target_len == sizeof(target)) { + info(udev_device->udev, "error reading db link %s: %m\n", filename); return -1; } + target[target_len] = '\0'; next = strchr(target, ' '); if (next != NULL) { @@ -1095,16 +1094,18 @@ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const goto out; len = readlink(path, target, sizeof(target)); - if (len > 0) { - target[len] = '\0'; - pos = strrchr(target, '/'); - if (pos != NULL) { - pos = &pos[1]; - dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos); - list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, pos, 0, 0); - val = udev_list_entry_get_value(list_entry); - } + if (len <= 0 || len == sizeof(target)) + goto out; + target[len] = '\0'; + + pos = strrchr(target, '/'); + if (pos != NULL) { + pos = &pos[1]; + dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos); + list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, pos, 0, 0); + val = udev_list_entry_get_value(list_entry); } + goto out; } diff --git a/libudev/libudev-queue.c b/libudev/libudev-queue.c index f06c9e8a..5a4a3dc0 100644 --- a/libudev/libudev-queue.c +++ b/libudev/libudev-queue.c @@ -488,7 +488,7 @@ struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev s = syspath; l = util_strpcpyl(&s, sizeof(syspath), udev_get_sys_path(udev_queue->udev), NULL); len = readlinkat(dirfd(dir), dent->d_name, s, l); - if (len < 0 || (size_t)len >= l) + if (len <= 0 || (size_t)len == l) continue; s[len] = '\0'; dbg(udev_queue->udev, "found '%s' [%s]\n", syspath, dent->d_name); diff --git a/udev/udev-node.c b/udev/udev-node.c index ceb1d52e..5c1b04b8 100644 --- a/udev/udev-node.c +++ b/udev/udev-node.c @@ -163,8 +163,8 @@ static int node_symlink(struct udev *udev, const char *node, const char *slink) int len; dbg(udev, "found existing symlink '%s'\n", slink); - len = readlink(slink, buf, sizeof(buf) - 1); - if (len > 0) { + len = readlink(slink, buf, sizeof(buf)); + if (len > 0 && len < (int)sizeof(buf)) { buf[len] = '\0'; if (strcmp(target, buf) == 0) { info(udev, "preserve already existing symlink '%s' to '%s'\n", diff --git a/udev/udev-watch.c b/udev/udev-watch.c index 7135d9f4..5fa60101 100644 --- a/udev/udev-watch.c +++ b/udev/udev-watch.c @@ -81,7 +81,7 @@ void udev_watch_restore(struct udev *udev) s = device; l = util_strpcpy(&s, sizeof(device), udev_get_sys_path(udev)); len = readlinkat(dirfd(dir), ent->d_name, s, l); - if (len <= 0 || len >= (ssize_t)l) + if (len <= 0 || len == (ssize_t)l) goto unlink; s[len] = '\0'; @@ -173,7 +173,7 @@ struct udev_device *udev_watch_lookup(struct udev *udev, int wd) s = majmin; l = util_strpcpy(&s, sizeof(majmin), udev_get_sys_path(udev)); len = readlink(filename, s, l); - if (len < 0 || (size_t)len >= l) + if (len <= 0 || (size_t)len == l) return NULL; s[len] = '\0'; -- 2.39.5