Permalink
Browse files

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).
  • Loading branch information...
fbuihuu committed Mar 20, 2018
1 parent 1f56e4c commit addc3e302dad239fb11cf280b0ce4761fe07e015
Showing with 31 additions and 8 deletions.
  1. +31 −8 src/tmpfiles/tmpfiles.c
@@ -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);
}

0 comments on commit addc3e3

Please sign in to comment.