tmpfiles: don't follow unsafe transitions in path_set_*()

Since all path_set_*() helpers don't follow symlinks, it's possible to use
chase_symlinks(CHASE_NOFOLLOW) flag to both open the files specified by the
passed paths and check their validity (unlike their counterpart fd_set_*()
helpers).
This commit is contained in:
Franck Bui 2018-03-20 08:58:48 +01:00
parent 1f56e4ce77
commit addc3e302d
1 changed files with 31 additions and 8 deletions

View File

@ -864,15 +864,38 @@ static int path_open_parent_safe(const char *path) {
return fd;
}
static int path_open_safe(const char *path) {
int fd;
/* path_open_safe() returns a file descriptor opened with O_PATH after
* verifying that the path doesn't contain unsafe transitions, except
* for its final component as the function does not follow symlink. */
assert(path);
if (!path_is_normalized(path)) {
log_error("Failed to open invalid path '%s'.", path);
return -EINVAL;
}
fd = chase_symlinks(path, NULL, CHASE_OPEN|CHASE_SAFE|CHASE_NOFOLLOW, NULL);
if (fd == -EPERM)
return log_error_errno(fd, "Unsafe symlinks encountered in %s, refusing.", path);
if (fd < 0)
return log_error_errno(fd, "Failed to validate path %s: %m", path);
return fd;
}
static int path_set_perms(Item *i, const char *path) {
_cleanup_close_ int fd = -1;
assert(i);
assert(path);
fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
fd = path_open_safe(path);
if (fd < 0)
return log_error_errno(errno, "Failed to open \"%s\" to adjust permissions: %m", path);
return fd;
return fd_set_perms(i, fd, NULL);
}
@ -945,9 +968,9 @@ static int path_set_xattrs(Item *i, const char *path) {
assert(i);
assert(path);
fd = open(path, O_CLOEXEC|O_NOFOLLOW|O_PATH);
fd = path_open_safe(path);
if (fd < 0)
return log_error_errno(errno, "Cannot open '%s': %m", path);
return fd;
return fd_set_xattrs(i, fd, NULL);
}
@ -1076,9 +1099,9 @@ static int path_set_acls(Item *item, const char *path) {
assert(item);
assert(path);
fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
fd = path_open_safe(path);
if (fd < 0)
return log_error_errno(errno, "Adjusting ACL of %s failed: %m", path);
return fd;
r = fd_set_acls(item, fd, NULL);
#endif
@ -1238,9 +1261,9 @@ static int path_set_attribute(Item *item, const char *path) {
if (!item->attribute_set || item->attribute_mask == 0)
return 0;
fd = open(path, O_CLOEXEC|O_NOFOLLOW|O_PATH);
fd = path_open_safe(path);
if (fd < 0)
return log_error_errno(errno, "Cannot open '%s': %m", path);
return fd;
return fd_set_attribute(item, fd, NULL);
}