int r;
assert(!FLAGS_SET(flags, CHASE_PREFIX_ROOT));
+ assert(!FLAGS_SET(flags, CHASE_MUST_BE_DIRECTORY|CHASE_MUST_BE_REGULAR));
assert(!FLAGS_SET(flags, CHASE_STEP|CHASE_EXTRACT_FILENAME));
assert(!FLAGS_SET(flags, CHASE_TRAIL_SLASH|CHASE_EXTRACT_FILENAME));
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
if (root_fd < 0)
return -errno;
- if (FLAGS_SET(flags, CHASE_TRAIL_SLASH))
- append_trail_slash = ENDSWITH_SET(buffer, "/", "/.");
+ if (ENDSWITH_SET(buffer, "/", "/.")) {
+ flags |= CHASE_MUST_BE_DIRECTORY;
+ if (FLAGS_SET(flags, CHASE_TRAIL_SLASH))
+ append_trail_slash = true;
+ } else if (dot_or_dot_dot(buffer) || endswith(buffer, "/.."))
+ flags |= CHASE_MUST_BE_DIRECTORY;
+
+ if (FLAGS_SET(flags, CHASE_PARENT))
+ flags |= CHASE_MUST_BE_DIRECTORY;
for (todo = buffer;;) {
_cleanup_free_ char *first = NULL;
close_and_replace(fd, child);
}
- if (FLAGS_SET(flags, CHASE_PARENT)) {
+ if (FLAGS_SET(flags, CHASE_MUST_BE_DIRECTORY)) {
r = stat_verify_directory(&st);
if (r < 0)
return r;
}
+ if (FLAGS_SET(flags, CHASE_MUST_BE_REGULAR)) {
+ r = stat_verify_regular(&st);
+ if (r < 0)
+ return r;
+ }
+
if (ret_path) {
if (FLAGS_SET(flags, CHASE_EXTRACT_FILENAME) && done) {
_cleanup_free_ char *f = NULL;
}
/* Then, try reading the D-Bus machine ID, unless it is a symlink */
- fd = chase_and_open("/var/lib/dbus/machine-id", root, CHASE_PREFIX_ROOT | CHASE_NOFOLLOW, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
+ fd = chase_and_open("/var/lib/dbus/machine-id", root, CHASE_PREFIX_ROOT|CHASE_NOFOLLOW|CHASE_MUST_BE_REGULAR, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
if (fd >= 0 && id128_read_fd(fd, ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, ret) >= 0) {
log_info("Initializing machine ID from D-Bus machine ID.");
return 0;
WITH_UMASK(0000) {
_cleanup_close_ int inode_fd = -EBADF;
- r = chase("/etc/machine-id", root, CHASE_PREFIX_ROOT, &etc_machine_id, &inode_fd);
+ r = chase("/etc/machine-id", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_REGULAR, &etc_machine_id, &inode_fd);
if (r == -ENOENT) {
_cleanup_close_ int etc_fd = -EBADF;
_cleanup_free_ char *etc = NULL;
- r = chase("/etc/", root, CHASE_PREFIX_ROOT|CHASE_MKDIR_0755, &etc, &etc_fd);
+ r = chase("/etc/", root, CHASE_PREFIX_ROOT|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY, &etc, &etc_fd);
if (r < 0)
return log_error_errno(r, "Failed to open '/etc/': %m");
if (write_run_machine_id) {
_cleanup_free_ char *run = NULL;
- r = chase("/run/", root, CHASE_PREFIX_ROOT|CHASE_MKDIR_0755, &run, &run_fd);
+ r = chase("/run/", root, CHASE_PREFIX_ROOT|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY, &run, &run_fd);
if (r < 0)
return log_error_errno(r, "Failed to open '/run/': %m");
unlink_run_machine_id = true;
} else {
- r = chase("/run/machine-id", root, CHASE_PREFIX_ROOT, &run_machine_id, /* ret_inode_fd= */ NULL);
+ r = chase("/run/machine-id", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_REGULAR, &run_machine_id, /* ret_inode_fd= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to open '/run/machine-id': %m");
}
_cleanup_close_ int etc_fd = -EBADF;
_cleanup_free_ char *etc = NULL;
- r = chase("/etc/", root, CHASE_PREFIX_ROOT, &etc, &etc_fd);
+ r = chase("/etc/", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_DIRECTORY, &etc, &etc_fd);
if (r < 0)
return log_error_errno(r, "Failed to open /etc/: %m");
/* Open /etc/ again after we transitioned into our own private mount namespace */
_cleanup_close_ int etc_fd_again = -EBADF;
- r = chase("/etc/", root, CHASE_PREFIX_ROOT, /* ret_path= */ NULL, &etc_fd_again);
+ r = chase("/etc/", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_DIRECTORY, /* ret_path= */ NULL, &etc_fd_again);
if (r < 0)
return log_error_errno(r, "Failed to open /etc/: %m");