X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=f904d03257f1b63e43d578ddd5c65b0b3aee744a;hp=03edafb952c3b9969a9fab4bc7e492fd2784fd61;hb=3a296a5fe6c06deb497b09ab29b8363761b2885d;hpb=99a720797c7779625c23de456c85ed0b3056bca6 diff --git a/src/shared/util.c b/src/shared/util.c index 03edafb95..f904d0325 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -350,7 +350,6 @@ int parse_uid(const char *s, uid_t* ret_uid) { int r; assert(s); - assert(ret_uid); r = safe_atolu(s, &ul); if (r < 0) @@ -369,7 +368,9 @@ int parse_uid(const char *s, uid_t* ret_uid) { if (uid == (uid_t) 0xFFFF) return -ENXIO; - *ret_uid = uid; + if (ret_uid) + *ret_uid = uid; + return 0; } @@ -1700,7 +1701,7 @@ int parse_size(const char *t, off_t base, off_t *size) { * sometimes SI decimal suffixes. This function can parse * both. Which one is the right way depends on the * context. Wikipedia suggests that SI is customary for - * hardrware metrics and network speeds, while IEC is + * hardware metrics and network speeds, while IEC is * customary for most data sizes used by software and volatile * (RAM) memory. Hence be careful which one you pick! * @@ -3917,7 +3918,7 @@ bool path_is_safe(const char *p) { if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../")) return false; - if (strlen(p) > PATH_MAX) + if (strlen(p)+1 > PATH_MAX) return false; /* The following two checks are not really dangerous, but hey, they still are confusing */ @@ -5923,9 +5924,22 @@ int fd_setcrtime(int fd, usec_t usec) { int chattr_fd(int fd, unsigned value, unsigned mask) { unsigned old_attr, new_attr; + struct stat st; assert(fd >= 0); + if (fstat(fd, &st) < 0) + return -errno; + + /* Explicitly check whether this is a regular file or + * directory. If it is anything else (such as a device node or + * fifo), then the ioctl will not hit the file systems but + * possibly drivers, where the ioctl might have different + * effects. Notably, DRM is using the same ioctl() number. */ + + if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) + return -ENOTTY; + if (mask == 0) return 0; @@ -5958,8 +5972,16 @@ int chattr_path(const char *p, unsigned value, unsigned mask) { } int read_attr_fd(int fd, unsigned *ret) { + struct stat st; + assert(fd >= 0); + if (fstat(fd, &st) < 0) + return -errno; + + if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) + return -ENOTTY; + if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0) return -errno;