chase: introduce CHASE_NO_SHORTCUT_MASK
This commit is contained in:
+18
-21
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user