chase: add new flag CHASE_MUST_BE_SOCKET
Just like CHASE_MUST_BE_DIRECTORY and CHASE_MUST_BE_REGULAR, but test if the inode is a socket.
This commit is contained in:
+18
-6
@@ -26,7 +26,10 @@
|
||||
CHASE_STEP | \
|
||||
CHASE_PROHIBIT_SYMLINKS | \
|
||||
CHASE_PARENT | \
|
||||
CHASE_MKDIR_0755)
|
||||
CHASE_MKDIR_0755 | \
|
||||
CHASE_MUST_BE_DIRECTORY | \
|
||||
CHASE_MUST_BE_REGULAR | \
|
||||
CHASE_MUST_BE_SOCKET)
|
||||
|
||||
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
|
||||
@@ -133,7 +136,6 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
|
||||
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_NO_AUTOFS|CHASE_TRIGGER_AUTOFS));
|
||||
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
|
||||
@@ -328,6 +330,10 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
|
||||
if (FLAGS_SET(flags, CHASE_PARENT))
|
||||
flags |= CHASE_MUST_BE_DIRECTORY;
|
||||
|
||||
/* If multiple flags are set now, fail immediately */
|
||||
if (FLAGS_SET(flags, CHASE_MUST_BE_DIRECTORY) + FLAGS_SET(flags, CHASE_MUST_BE_REGULAR) + FLAGS_SET(flags, CHASE_MUST_BE_SOCKET) > 1)
|
||||
return -EBADSLT;
|
||||
|
||||
for (todo = buffer;;) {
|
||||
_cleanup_free_ char *first = NULL;
|
||||
_cleanup_close_ int child = -EBADF;
|
||||
@@ -566,6 +572,12 @@ success:
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, CHASE_MUST_BE_SOCKET)) {
|
||||
r = stat_verify_socket(&st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret_path) {
|
||||
@@ -872,7 +884,7 @@ int chase_and_opendir(const char *path, const char *root, ChaseFlags chase_flags
|
||||
DIR *d;
|
||||
int r;
|
||||
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR|CHASE_MUST_BE_SOCKET)));
|
||||
assert(ret_dir);
|
||||
|
||||
if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
|
||||
@@ -970,7 +982,7 @@ int chase_and_fopen_unlocked(
|
||||
int mode_flags, r;
|
||||
|
||||
assert(path);
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT|CHASE_MUST_BE_DIRECTORY)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT|CHASE_MUST_BE_DIRECTORY|CHASE_MUST_BE_SOCKET)));
|
||||
assert(open_flags);
|
||||
assert(ret_file);
|
||||
|
||||
@@ -1040,7 +1052,7 @@ int chase_and_openat(
|
||||
_cleanup_free_ char *p = NULL, *fname = NULL;
|
||||
int r;
|
||||
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_SOCKET)));
|
||||
|
||||
XOpenFlags xopen_flags = 0;
|
||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_DIRECTORY))
|
||||
@@ -1086,7 +1098,7 @@ int chase_and_opendirat(int dir_fd, const char *path, ChaseFlags chase_flags, ch
|
||||
DIR *d;
|
||||
int r;
|
||||
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR|CHASE_MUST_BE_SOCKET)));
|
||||
assert(ret_dir);
|
||||
|
||||
if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef enum ChaseFlags {
|
||||
CHASE_EXTRACT_FILENAME = 1 << 13, /* Only return the last component of the resolved path */
|
||||
CHASE_MUST_BE_DIRECTORY = 1 << 14, /* Fail if returned inode fd is not a dir */
|
||||
CHASE_MUST_BE_REGULAR = 1 << 15, /* Fail if returned inode fd is not a regular file */
|
||||
CHASE_MUST_BE_SOCKET = 1 << 16, /* Fail if returned inode fd is not a socket */
|
||||
} ChaseFlags;
|
||||
|
||||
bool unsafe_transition(const struct stat *a, const struct stat *b);
|
||||
|
||||
Reference in New Issue
Block a user