diff options
author | Martin Pitt <mpitt@debian.org> | 2017-03-02 10:44:39 +0100 |
---|---|---|
committer | Martin Pitt <mpitt@debian.org> | 2017-03-02 10:44:39 +0100 |
commit | 2897b343851c95927e26f45bea8c40da605dbed1 (patch) | |
tree | c15ec2f4b562d39a818acc5d65ae58944791dba9 /src/libsystemd/sd-device/sd-device.c | |
parent | 8a584da2774aca0b14c8aacef574e93d943d470e (diff) | |
download | systemd-2897b343851c95927e26f45bea8c40da605dbed1.tar.gz |
New upstream version 233
Diffstat (limited to 'src/libsystemd/sd-device/sd-device.c')
-rw-r--r-- | src/libsystemd/sd-device/sd-device.c | 50 |
1 files changed, 20 insertions, 30 deletions
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 411453e08d..04ead29338 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -28,6 +28,7 @@ #include "device-internal.h" #include "device-private.h" #include "device-util.h" +#include "dirent-util.h" #include "fd-util.h" #include "fileio.h" #include "fs-util.h" @@ -164,7 +165,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { } if (verify) { - r = readlink_and_canonicalize(_syspath, &syspath); + r = readlink_and_canonicalize(_syspath, NULL, &syspath); if (r == -ENOENT) /* the device does not exist (any more?) */ return -ENODEV; @@ -559,7 +560,7 @@ int device_read_uevent_file(sd_device *device) { value = &uevent[i]; state = VALUE; - /* fall through to handle empty property */ + /* fall through */ /* to handle empty property */ case VALUE: if (strchr(NEWLINE, uevent[i])) { uevent[i] = '\0'; @@ -1627,7 +1628,7 @@ static int device_sysattrs_read_all(sd_device *device) { if (r < 0) return r; - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + FOREACH_DIRENT_ALL(dent, dir, return -errno) { char *path; struct stat statbuf; @@ -1858,8 +1859,7 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, _cleanup_free_ char *value = NULL; const char *syspath; char *path; - struct stat statbuf; - size_t value_len = 0; + size_t len = 0; ssize_t size; int r; @@ -1877,8 +1877,14 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, return r; path = strjoina(syspath, "/", sysattr); - r = lstat(path, &statbuf); - if (r < 0) { + + fd = open(path, O_WRONLY | O_CLOEXEC | O_NOFOLLOW); + if (fd < 0) { + if (errno == ELOOP) + return -EINVAL; + if (errno == EISDIR) + return -EISDIR; + value = strdup(""); if (!value) return -ENOMEM; @@ -1890,46 +1896,30 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, return -ENXIO; } - if (S_ISLNK(statbuf.st_mode)) - return -EINVAL; - - /* skip directories */ - if (S_ISDIR(statbuf.st_mode)) - return -EISDIR; - - /* skip non-readable files */ - if ((statbuf.st_mode & S_IRUSR) == 0) - return -EACCES; - - value_len = strlen(_value); + len = strlen(_value); /* drop trailing newlines */ - while (value_len > 0 && _value[value_len - 1] == '\n') - _value[--value_len] = '\0'; + while (len > 0 && _value[len - 1] == '\n') + len --; /* value length is limited to 4k */ - if (value_len > 4096) + if (len > 4096) return -EINVAL; - fd = open(path, O_WRONLY | O_CLOEXEC); - if (fd < 0) - return -errno; - - value = strdup(_value); + value = strndup(_value, len); if (!value) return -ENOMEM; - size = write(fd, value, value_len); + size = write(fd, value, len); if (size < 0) return -errno; - if ((size_t)size != value_len) + if ((size_t)size != len) return -EIO; r = device_add_sysattr_value(device, sysattr, value); if (r < 0) return r; - value = NULL; return 0; |