X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fsystemd.git;a=blobdiff_plain;f=src%2Ftmpfiles%2Ftmpfiles.c;h=8b6342b2e446968eeb90d0c252beeada9063d8c7;hp=31d4c923a272c3d39abb0aa1778e81ec4ac774d7;hb=b206ac8e54a3656b681b2f6031c7cd0feb7f5e26;hpb=14f3480af1f5b5884827977fedecf0d7bb61ebab diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 31d4c923a27..8b6342b2e44 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -772,6 +772,7 @@ static bool hardlink_vulnerable(const struct stat *st) { static int fd_set_perms(Item *i, int fd, const struct stat *st) { _cleanup_free_ char *path = NULL; + struct stat stbuf; int r; assert(i); @@ -784,6 +785,12 @@ static int fd_set_perms(Item *i, int fd, const struct stat *st) { if (!i->mode_set && !i->uid_set && !i->gid_set) goto shortcut; + if (!st) { + if (fstat(fd, &stbuf) < 0) + return log_error_errno(errno, "fstat(%s) failed: %m", path); + st = &stbuf; + } + if (hardlink_vulnerable(st)) { log_error("Refusing to set permissions on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.", path); return -EPERM; @@ -837,7 +844,7 @@ shortcut: static int path_set_perms(Item *i, const char *path) { _cleanup_close_ int fd = -1; - struct stat st; + struct stat stbuf, *st = NULL; assert(i); assert(path); @@ -857,13 +864,20 @@ static int path_set_perms(Item *i, const char *path) { return r; } - if (fstat(fd, &st) < 0) - return log_error_errno(errno, "Failed to fstat() file %s: %m", path); + if (i->type == EMPTY_DIRECTORY) { + /* FIXME: introduce fd_is_dir() helper ? */ + if (fstat(fd, &stbuf) < 0) + return log_error_errno(errno, "Failed to fstat() file %s: %m", path); + + if (!S_ISDIR(stbuf.st_mode)) { + log_error("'%s' already exists and is not a directory. ", path); + return -EEXIST; + } - if (i->type == EMPTY_DIRECTORY && !S_ISDIR(st.st_mode)) - return log_error_errno(EEXIST, "'%s' already exists and is not a directory. ", path); + st = &stbuf; + } - return fd_set_perms(i, fd, &st); + return fd_set_perms(i, fd, st); } static int parse_xattrs_from_arg(Item *i) { @@ -1011,15 +1025,21 @@ static int fd_set_acls(Item *item, int fd, const struct stat *st) { #if HAVE_ACL char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; _cleanup_free_ char *path = NULL; + struct stat stbuf; assert(item); assert(fd); - assert(st); r = fd_get_path(fd, &path); if (r < 0) return r; + if (!st) { + if (fstat(fd, &stbuf) < 0) + return log_error_errno(errno, "fstat(%s) failed: %m", path); + st = &stbuf; + } + if (hardlink_vulnerable(st)) { log_error("Refusing to set ACLs on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.", path); return -EPERM; @@ -1055,7 +1075,6 @@ static int path_set_acls(Item *item, const char *path) { int r = 0; #if HAVE_ACL _cleanup_close_ int fd = -1; - struct stat st; assert(item); assert(path); @@ -1064,10 +1083,7 @@ static int path_set_acls(Item *item, const char *path) { if (fd < 0) return log_error_errno(errno, "Adjusting ACL of %s failed: %m", path); - if (fstat(fd, &st) < 0) - return log_error_errno(errno, "Failed to fstat() file %s: %m", path); - - r = fd_set_acls(item, fd, &st); + r = fd_set_acls(item, fd, NULL); #endif return r; } @@ -1174,6 +1190,7 @@ static int parse_attribute_from_arg(Item *item) { static int fd_set_attribute(Item *item, int fd, const struct stat *st) { _cleanup_close_ int procfs_fd = -1; _cleanup_free_ char *path = NULL; + struct stat stbuf; unsigned f; int r; @@ -1184,6 +1201,12 @@ static int fd_set_attribute(Item *item, int fd, const struct stat *st) { if (r < 0) return r; + if (!st) { + if (fstat(fd, &stbuf) < 0) + return log_error_errno(errno, "fstat(%s) failed: %m", path); + st = &stbuf; + } + /* Issuing the file attribute ioctls on device nodes is not * safe, as that will be delivered to the drivers, not the * file system containing the device node. */ @@ -1214,7 +1237,6 @@ static int fd_set_attribute(Item *item, int fd, const struct stat *st) { static int path_set_attribute(Item *item, const char *path) { _cleanup_close_ int fd = -1; - struct stat st; if (!item->attribute_set || item->attribute_mask == 0) return 0; @@ -1223,10 +1245,7 @@ static int path_set_attribute(Item *item, const char *path) { if (fd < 0) return log_error_errno(errno, "Cannot open '%s': %m", path); - if (fstat(fd, &st) < 0) - return log_error_errno(errno, "Cannot stat '%s': %m", path); - - return fd_set_attribute(item, fd, &st); + return fd_set_attribute(item, fd, NULL); } static int write_one_file(Item *i, const char *path) {