fs-util: add new CHASE_WARN flag to chase_symlinks()
This flag can be used to make chase_symlinks() emit a warning when it encounters an error. Such flag can be useful for generating a comprehensive and detailed warning since chase_symlinks() can generate a warning with a full context. For now only warnings for unsafe transitions are produced.
This commit is contained in:
parent
0abf94923b
commit
fd74c6f3f8
|
@ -15,6 +15,7 @@
|
|||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "locale-util.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "missing.h"
|
||||
|
@ -644,6 +645,20 @@ static bool safe_transition(const struct stat *a, const struct stat *b) {
|
|||
return a->st_uid == b->st_uid; /* Otherwise we need to stay within the same UID */
|
||||
}
|
||||
|
||||
static int log_unsafe_transition(int a, int b, const char *path, unsigned flags) {
|
||||
_cleanup_free_ char *n1 = NULL, *n2 = NULL;
|
||||
|
||||
if (!FLAGS_SET(flags, CHASE_WARN))
|
||||
return -EPERM;
|
||||
|
||||
(void) fd_get_path(a, &n1);
|
||||
(void) fd_get_path(b, &n2);
|
||||
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EPERM),
|
||||
"Detected unsafe path transition %s %s %s during canonicalization of %s.",
|
||||
n1, special_glyph(ARROW), n2, path);
|
||||
}
|
||||
|
||||
int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) {
|
||||
_cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
@ -819,7 +834,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
return -errno;
|
||||
|
||||
if (!safe_transition(&previous_stat, &st))
|
||||
return -EPERM;
|
||||
return log_unsafe_transition(fd, fd_parent, path, flags);
|
||||
|
||||
previous_stat = st;
|
||||
}
|
||||
|
@ -860,7 +875,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
return -errno;
|
||||
if ((flags & CHASE_SAFE) &&
|
||||
!safe_transition(&previous_stat, &st))
|
||||
return -EPERM;
|
||||
return log_unsafe_transition(fd, child, path, flags);
|
||||
|
||||
previous_stat = st;
|
||||
|
||||
|
@ -899,7 +914,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
return -errno;
|
||||
|
||||
if (!safe_transition(&previous_stat, &st))
|
||||
return -EPERM;
|
||||
return log_unsafe_transition(child, fd, path, flags);
|
||||
|
||||
previous_stat = st;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ enum {
|
|||
CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */
|
||||
CHASE_STEP = 1 << 6, /* If set, just execute a single step of the normalization */
|
||||
CHASE_NOFOLLOW = 1 << 7, /* Only valid with CHASE_OPEN: when the path's right-most component refers to symlink return O_PATH fd of the symlink, rather than following it. */
|
||||
CHASE_WARN = 1 << 8, /* Emit an appropriate warning when an error is encountered */
|
||||
};
|
||||
|
||||
/* How many iterations to execute before returning -ELOOP */
|
||||
|
|
Loading…
Reference in New Issue