From: Yu Watanabe Date: Tue, 19 Aug 2025 14:45:40 +0000 (+0900) Subject: chase: introduce CHASE_NO_SHORTCUT_MASK X-Git-Tag: v258-rc3~3^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9dcd034085559de970092bce47de94d02c839ba5;p=thirdparty%2Fsystemd.git chase: introduce CHASE_NO_SHORTCUT_MASK --- diff --git a/src/basic/chase.c b/src/basic/chase.c index 68bb9816ce4..9219209421c 100644 --- a/src/basic/chase.c +++ b/src/basic/chase.c @@ -18,6 +18,15 @@ #include "strv.h" #include "user-util.h" +#define CHASE_NO_SHORTCUT_MASK \ + (CHASE_NONEXISTENT | \ + CHASE_NO_AUTOFS | \ + CHASE_SAFE | \ + CHASE_STEP | \ + CHASE_PROHIBIT_SYMLINKS | \ + CHASE_PARENT | \ + CHASE_MKDIR_0755) + bool unsafe_transition(const struct stat *a, const struct stat *b) { /* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to * privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files @@ -218,11 +227,7 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int flags &= ~CHASE_AT_RESOLVE_IN_ROOT; } - if (!(flags & - (CHASE_AT_RESOLVE_IN_ROOT|CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_STEP| - CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_PARENT)) && - !ret_path && ret_fd) { - + if (!ret_path && ret_fd && (flags & (CHASE_AT_RESOLVE_IN_ROOT|CHASE_NO_SHORTCUT_MASK)) == 0) { /* Shortcut the ret_fd case if the caller isn't interested in the actual path and has no root * set and doesn't care about any of the other special features we provide either. */ r = openat(dir_fd, path, O_PATH|O_CLOEXEC|(FLAGS_SET(flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0)); @@ -782,8 +787,7 @@ int chase_and_open( assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))); - if (empty_or_root(root) && !ret_path && - (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) + if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) /* Shortcut this call if none of the special features of this call are requested */ return xopenat_full(AT_FDCWD, path, open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0), @@ -821,8 +825,7 @@ int chase_and_opendir(const char *path, const char *root, ChaseFlags chase_flags assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))); assert(ret_dir); - if (empty_or_root(root) && !ret_path && - (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) { + if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) { /* Shortcut this call if none of the special features of this call are requested */ d = opendir(path); if (!d) @@ -857,8 +860,7 @@ int chase_and_stat(const char *path, const char *root, ChaseFlags chase_flags, c assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))); assert(ret_stat); - if (empty_or_root(root) && !ret_path && - (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) + if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) /* Shortcut this call if none of the special features of this call are requested */ return RET_NERRNO(fstatat(AT_FDCWD, path, ret_stat, FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0)); @@ -885,8 +887,7 @@ int chase_and_access(const char *path, const char *root, ChaseFlags chase_flags, assert(path); assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))); - if (empty_or_root(root) && !ret_path && - (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) + if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) /* Shortcut this call if none of the special features of this call are requested */ return RET_NERRNO(faccessat(AT_FDCWD, path, access_mode, FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0)); @@ -991,8 +992,7 @@ int chase_and_openat( assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))); - if (dir_fd == AT_FDCWD && !ret_path && - (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) + if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) /* Shortcut this call if none of the special features of this call are requested */ return xopenat_full(dir_fd, path, open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0), @@ -1028,8 +1028,7 @@ int chase_and_opendirat(int dir_fd, const char *path, ChaseFlags chase_flags, ch assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))); assert(ret_dir); - if (dir_fd == AT_FDCWD && !ret_path && - (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) { + if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) { /* Shortcut this call if none of the special features of this call are requested */ d = opendir(path); if (!d) @@ -1064,8 +1063,7 @@ int chase_and_statat(int dir_fd, const char *path, ChaseFlags chase_flags, char assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))); assert(ret_stat); - if (dir_fd == AT_FDCWD && !ret_path && - (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) + if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) /* Shortcut this call if none of the special features of this call are requested */ return RET_NERRNO(fstatat(AT_FDCWD, path, ret_stat, FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0)); @@ -1092,8 +1090,7 @@ int chase_and_accessat(int dir_fd, const char *path, ChaseFlags chase_flags, int assert(path); assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))); - if (dir_fd == AT_FDCWD && !ret_path && - (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) + if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) /* Shortcut this call if none of the special features of this call are requested */ return RET_NERRNO(faccessat(AT_FDCWD, path, access_mode, FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0));