label: plumb label_context through LabelOps
SELinux labeling with --root/--image needs per-call context to carry an alternate policy database and root prefix. The current LabelOps interface has no way to pass this, forcing any solution to rely on global state. Add a LabelContext *label_context to the label_ops callbacks and all intermediate layers. Generic filesystem functions that most callers use (xopenat_full, write_string_file_full, etc.) get a _label variant carrying the extra parameter, with inline wrappers preserving the original signatures so the vast majority of call sites remain untouched. Signed-off-by: Simon de Vlieger <cmdr@supakeen.com>
This commit is contained in:
@@ -665,7 +665,7 @@ static void write_env_var(FILE *f, const char *v) {
|
||||
fputc_unlocked('\n', f);
|
||||
}
|
||||
|
||||
int write_env_file(int dir_fd, const char *fname, char **headers, char **l, WriteEnvFileFlags flags) {
|
||||
int write_env_file_label(int dir_fd, const char *fname, char **headers, char **l, WriteEnvFileFlags flags, LabelContext *label_context) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int r;
|
||||
@@ -675,7 +675,7 @@ int write_env_file(int dir_fd, const char *fname, char **headers, char **l, Writ
|
||||
|
||||
bool call_label_ops_post = false;
|
||||
if (FLAGS_SET(flags, WRITE_ENV_FILE_LABEL)) {
|
||||
r = label_ops_pre(dir_fd, fname, S_IFREG);
|
||||
r = label_ops_pre(dir_fd, fname, S_IFREG, label_context);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -683,7 +683,7 @@ int write_env_file(int dir_fd, const char *fname, char **headers, char **l, Writ
|
||||
}
|
||||
|
||||
r = fopen_tmpfile_linkable_at(dir_fd, fname, O_WRONLY|O_CLOEXEC, &p, &f);
|
||||
int k = call_label_ops_post ? label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fname, /* created= */ !!f) : 0;
|
||||
int k = call_label_ops_post ? label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fname, /* created= */ !!f, label_context) : 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
CLEANUP_TMPFILE_AT(dir_fd, p);
|
||||
@@ -717,5 +717,5 @@ int write_vconsole_conf(int dir_fd, const char *fname, char **l) {
|
||||
"# Written by systemd-localed(8) or systemd-firstboot(1), read by systemd-localed",
|
||||
"# and systemd-vconsole-setup(8). Use localectl(1) to update this file.");
|
||||
|
||||
return write_env_file(dir_fd, fname, headers, l, WRITE_ENV_FILE_LABEL);
|
||||
return write_env_file_label(dir_fd, fname, headers, l, WRITE_ENV_FILE_LABEL, /* label_context= */ NULL);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,10 @@ typedef enum WriteEnvFileFlags {
|
||||
WRITE_ENV_FILE_LABEL = 1 << 0,
|
||||
} WriteEnvFileFlags;
|
||||
|
||||
int write_env_file(int dir_fd, const char *fname, char **headers, char **l, WriteEnvFileFlags flags);
|
||||
int write_env_file_label(int dir_fd, const char *fname, char **headers, char **l, WriteEnvFileFlags flags, LabelContext *label_context);
|
||||
static inline int write_env_file(int dir_fd, const char *fname, char **headers, char **l, WriteEnvFileFlags flags) {
|
||||
return write_env_file_label(dir_fd, fname, headers, l, flags, /* label_context= */ NULL);
|
||||
}
|
||||
|
||||
int write_vconsole_conf(int dir_fd, const char *fname, char **l);
|
||||
|
||||
|
||||
+10
-8
@@ -219,7 +219,8 @@ static int write_string_file_atomic_at(
|
||||
const char *fn,
|
||||
const char *line,
|
||||
WriteStringFileFlags flags,
|
||||
const struct timespec *ts) {
|
||||
const struct timespec *ts,
|
||||
LabelContext *label_context) {
|
||||
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
@@ -235,7 +236,7 @@ static int write_string_file_atomic_at(
|
||||
|
||||
bool call_label_ops_post = false;
|
||||
if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL)) {
|
||||
r = label_ops_pre(dir_fd, fn, mode);
|
||||
r = label_ops_pre(dir_fd, fn, mode, label_context);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -243,7 +244,7 @@ static int write_string_file_atomic_at(
|
||||
}
|
||||
|
||||
r = fopen_temporary_at(dir_fd, fn, &f, &p);
|
||||
int k = call_label_ops_post ? label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f) : 0;
|
||||
int k = call_label_ops_post ? label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f, label_context) : 0;
|
||||
/* If fopen_temporary_at() failed in the above, propagate the error code, and ignore failures in
|
||||
* label_ops_post(). */
|
||||
if (r < 0)
|
||||
@@ -276,13 +277,14 @@ static int write_string_file_atomic_at(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_string_file_full(
|
||||
int write_string_file_full_label(
|
||||
int dir_fd,
|
||||
const char *fn,
|
||||
const char *line,
|
||||
WriteStringFileFlags flags,
|
||||
const struct timespec *ts,
|
||||
const char *label_fn) {
|
||||
const char *label_fn,
|
||||
LabelContext *label_context) {
|
||||
|
||||
bool made_file = false;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
@@ -307,7 +309,7 @@ int write_string_file_full(
|
||||
assert(fn);
|
||||
assert(flags & WRITE_STRING_FILE_CREATE);
|
||||
|
||||
r = write_string_file_atomic_at(dir_fd, fn, line, flags, ts);
|
||||
r = write_string_file_atomic_at(dir_fd, fn, line, flags, ts, label_context);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@@ -326,7 +328,7 @@ int write_string_file_full(
|
||||
bool call_label_ops_post = false;
|
||||
|
||||
if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) {
|
||||
r = label_ops_pre(dir_fd, label_fn ?: fn, mode);
|
||||
r = label_ops_pre(dir_fd, label_fn ?: fn, mode, label_context);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@@ -345,7 +347,7 @@ int write_string_file_full(
|
||||
if (call_label_ops_post)
|
||||
/* If openat_report_new() failed in the above, propagate the error code, and ignore
|
||||
* failures in label_ops_post(). */
|
||||
RET_GATHER(r, label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, made_file));
|
||||
RET_GATHER(r, label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, made_file, label_context));
|
||||
}
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
+4
-1
@@ -45,7 +45,10 @@ static inline int write_string_stream(FILE *f, const char *line, WriteStringFile
|
||||
return write_string_stream_full(f, line, flags, NULL);
|
||||
}
|
||||
|
||||
int write_string_file_full(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts, const char *label_fn);
|
||||
int write_string_file_full_label(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts, const char *label_fn, LabelContext *label_context);
|
||||
static inline int write_string_file_full(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts, const char *label_fn) {
|
||||
return write_string_file_full_label(dir_fd, fn, line, flags, ts, label_fn, /* label_context= */ NULL);
|
||||
}
|
||||
static inline int write_string_file_at(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags) {
|
||||
return write_string_file_full(dir_fd, fn, line, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ typedef struct dual_timestamp dual_timestamp;
|
||||
typedef struct triple_timestamp triple_timestamp;
|
||||
typedef struct Compressor Compressor;
|
||||
typedef struct ConfFile ConfFile;
|
||||
typedef struct LabelContext LabelContext;
|
||||
typedef struct LockFile LockFile;
|
||||
typedef struct PidRef PidRef;
|
||||
typedef struct Prioq Prioq;
|
||||
|
||||
+13
-12
@@ -461,7 +461,7 @@ int symlinkat_idempotent(const char *target, int atfd, const char *linkpath, boo
|
||||
return 0;
|
||||
}
|
||||
|
||||
int symlinkat_atomic_full(const char *target, int atfd, const char *linkpath, SymlinkFlags flags) {
|
||||
int symlinkat_atomic_full_label(const char *target, int atfd, const char *linkpath, SymlinkFlags flags, LabelContext *label_context) {
|
||||
int r;
|
||||
|
||||
assert(target);
|
||||
@@ -483,7 +483,7 @@ int symlinkat_atomic_full(const char *target, int atfd, const char *linkpath, Sy
|
||||
|
||||
bool call_label_ops_post = false;
|
||||
if (FLAGS_SET(flags, SYMLINK_LABEL)) {
|
||||
r = label_ops_pre(atfd, linkpath, S_IFLNK);
|
||||
r = label_ops_pre(atfd, linkpath, S_IFLNK, label_context);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -492,7 +492,7 @@ int symlinkat_atomic_full(const char *target, int atfd, const char *linkpath, Sy
|
||||
|
||||
r = RET_NERRNO(symlinkat(target, atfd, t));
|
||||
if (call_label_ops_post)
|
||||
RET_GATHER(r, label_ops_post(atfd, t, /* created= */ r >= 0));
|
||||
RET_GATHER(r, label_ops_post(atfd, t, /* created= */ r >= 0, label_context));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1035,7 +1035,7 @@ int parse_cifs_service(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode) {
|
||||
int open_mkdir_at_full_label(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode, LabelContext *label_context) {
|
||||
_cleanup_close_ int fd = -EBADF, parent_fd = -EBADF;
|
||||
_cleanup_free_ char *fname = NULL, *parent = NULL;
|
||||
int r;
|
||||
@@ -1071,7 +1071,7 @@ int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_
|
||||
path = fname;
|
||||
}
|
||||
|
||||
fd = xopenat_full(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, xopen_flags, mode);
|
||||
fd = xopenat_full_label(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, xopen_flags, mode, label_context);
|
||||
if (IN_SET(fd, -ELOOP, -ENOTDIR))
|
||||
return -EEXIST;
|
||||
if (fd < 0)
|
||||
@@ -1171,7 +1171,7 @@ static int openat_with_automount(int dir_fd, const char *path, int open_flags, m
|
||||
return RET_NERRNO(openat(dir_fd, path, open_flags, mode));
|
||||
}
|
||||
|
||||
int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) {
|
||||
int xopenat_full_label(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LabelContext *label_context) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
bool made_dir = false, made_file = false;
|
||||
int r;
|
||||
@@ -1276,7 +1276,7 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
bool call_label_ops_post = false;
|
||||
|
||||
if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
|
||||
r = label_ops_pre(dir_fd, path, FLAGS_SET(open_flags, O_DIRECTORY) ? S_IFDIR : S_IFREG);
|
||||
r = label_ops_pre(dir_fd, path, FLAGS_SET(open_flags, O_DIRECTORY) ? S_IFDIR : S_IFREG, label_context);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1433,7 +1433,7 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
if (call_label_ops_post) {
|
||||
call_label_ops_post = false;
|
||||
|
||||
r = label_ops_post(fd, /* path= */ NULL, made_file || made_dir);
|
||||
r = label_ops_post(fd, /* path= */ NULL, made_file || made_dir, label_context);
|
||||
if (r < 0)
|
||||
goto error;
|
||||
}
|
||||
@@ -1448,7 +1448,7 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
|
||||
error:
|
||||
if (call_label_ops_post)
|
||||
(void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : path, made_dir || made_file);
|
||||
(void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : path, made_dir || made_file, label_context);
|
||||
|
||||
if (made_dir || made_file)
|
||||
(void) unlinkat(dir_fd, path, made_dir ? AT_REMOVEDIR : 0);
|
||||
@@ -1456,14 +1456,15 @@ error:
|
||||
return r;
|
||||
}
|
||||
|
||||
int xopenat_lock_full(
|
||||
int xopenat_lock_full_label(
|
||||
int dir_fd,
|
||||
const char *path,
|
||||
int open_flags,
|
||||
XOpenFlags xopen_flags,
|
||||
mode_t mode,
|
||||
LockType locktype,
|
||||
int operation) {
|
||||
int operation,
|
||||
LabelContext *label_context) {
|
||||
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int r;
|
||||
@@ -1479,7 +1480,7 @@ int xopenat_lock_full(
|
||||
for (;;) {
|
||||
struct stat st;
|
||||
|
||||
fd = xopenat_full(dir_fd, path, open_flags, xopen_flags, mode);
|
||||
fd = xopenat_full_label(dir_fd, path, open_flags, xopen_flags, mode, label_context);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
|
||||
+16
-4
@@ -58,7 +58,10 @@ typedef enum SymlinkFlags {
|
||||
SYMLINK_LABEL = 1 << 1,
|
||||
} SymlinkFlags;
|
||||
|
||||
int symlinkat_atomic_full(const char *target, int atfd, const char *linkpath, SymlinkFlags flags);
|
||||
int symlinkat_atomic_full_label(const char *target, int atfd, const char *linkpath, SymlinkFlags flags, LabelContext *label_context);
|
||||
static inline int symlinkat_atomic_full(const char *target, int atfd, const char *linkpath, SymlinkFlags flags) {
|
||||
return symlinkat_atomic_full_label(target, atfd, linkpath, flags, /* label_context= */ NULL);
|
||||
}
|
||||
static inline int symlink_atomic(const char *target, const char *linkpath) {
|
||||
return symlinkat_atomic_full(target, AT_FDCWD, linkpath, 0);
|
||||
}
|
||||
@@ -119,7 +122,10 @@ typedef enum XOpenFlags {
|
||||
XO_AUTO_RW_RO = 1 << 7, /* Open in O_RDWR mode if possible, O_RDONLY if not */
|
||||
} XOpenFlags;
|
||||
|
||||
int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode);
|
||||
int open_mkdir_at_full_label(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode, LabelContext *label_context);
|
||||
static inline int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode) {
|
||||
return open_mkdir_at_full_label(dirfd, path, flags, xopen_flags, mode, /* label_context= */ NULL);
|
||||
}
|
||||
static inline int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) {
|
||||
return open_mkdir_at_full(dirfd, path, flags, 0, mode);
|
||||
}
|
||||
@@ -129,12 +135,18 @@ static inline int open_mkdir(const char *path, int flags, mode_t mode) {
|
||||
|
||||
int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created);
|
||||
|
||||
int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode);
|
||||
int xopenat_full_label(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LabelContext *label_context);
|
||||
static inline int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) {
|
||||
return xopenat_full_label(dir_fd, path, open_flags, xopen_flags, mode, /* label_context= */ NULL);
|
||||
}
|
||||
static inline int xopenat(int dir_fd, const char *path, int open_flags) {
|
||||
return xopenat_full(dir_fd, path, open_flags, 0, MODE_INVALID);
|
||||
}
|
||||
|
||||
int xopenat_lock_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation);
|
||||
int xopenat_lock_full_label(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation, LabelContext *label_context);
|
||||
static inline int xopenat_lock_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation) {
|
||||
return xopenat_lock_full_label(dir_fd, path, open_flags, xopen_flags, mode, locktype, operation, /* label_context= */ NULL);
|
||||
}
|
||||
static inline int xopenat_lock(int dir_fd, const char *path, int open_flags, LockType locktype, int operation) {
|
||||
return xopenat_lock_full(dir_fd, path, open_flags, 0, 0, locktype, operation);
|
||||
}
|
||||
|
||||
@@ -18,16 +18,16 @@ void label_ops_reset(void) {
|
||||
label_ops = NULL;
|
||||
}
|
||||
|
||||
int label_ops_pre(int dir_fd, const char *path, mode_t mode) {
|
||||
int label_ops_pre(int dir_fd, const char *path, mode_t mode, LabelContext *label_context) {
|
||||
if (!label_ops || !label_ops->pre)
|
||||
return 0;
|
||||
|
||||
return label_ops->pre(dir_fd, path, mode);
|
||||
return label_ops->pre(dir_fd, path, mode, label_context);
|
||||
}
|
||||
|
||||
int label_ops_post(int dir_fd, const char *path, bool created) {
|
||||
int label_ops_post(int dir_fd, const char *path, bool created, LabelContext *label_context) {
|
||||
if (!label_ops || !label_ops->post)
|
||||
return 0;
|
||||
|
||||
return label_ops->post(dir_fd, path, created);
|
||||
return label_ops->post(dir_fd, path, created, label_context);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include "forward.h"
|
||||
|
||||
typedef struct LabelOps {
|
||||
int (*pre)(int dir_fd, const char *path, mode_t mode);
|
||||
int (*post)(int dir_fd, const char *path, bool created);
|
||||
int (*pre)(int dir_fd, const char *path, mode_t mode, LabelContext *label_context);
|
||||
int (*post)(int dir_fd, const char *path, bool created, LabelContext *label_context);
|
||||
} LabelOps;
|
||||
|
||||
int label_ops_set(const LabelOps *label_ops);
|
||||
void label_ops_reset(void);
|
||||
|
||||
int label_ops_pre(int dir_fd, const char *path, mode_t mode);
|
||||
int label_ops_post(int dir_fd, const char *path, bool created);
|
||||
int label_ops_pre(int dir_fd, const char *path, mode_t mode, LabelContext *label_context);
|
||||
int label_ops_post(int dir_fd, const char *path, bool created, LabelContext *label_context);
|
||||
|
||||
+22
-21
@@ -25,16 +25,17 @@ int mkdirat_safe_internal(
|
||||
uid_t uid,
|
||||
gid_t gid,
|
||||
MkdirFlags flags,
|
||||
mkdirat_func_t _mkdirat) {
|
||||
mkdirat_func_t _mkdirat,
|
||||
LabelContext *label_context) {
|
||||
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(mode != MODE_INVALID);
|
||||
assert(_mkdirat && _mkdirat != mkdirat);
|
||||
assert(_mkdirat);
|
||||
|
||||
r = _mkdirat(dir_fd, path, mode);
|
||||
r = _mkdirat(dir_fd, path, mode, label_context);
|
||||
if (r >= 0)
|
||||
return chmod_and_chown_at(dir_fd, path, mode, uid, gid);
|
||||
if (r != -EEXIST)
|
||||
@@ -52,7 +53,7 @@ int mkdirat_safe_internal(
|
||||
if (r == 0)
|
||||
return mkdirat_safe_internal(dir_fd, p, mode, uid, gid,
|
||||
flags & ~MKDIR_FOLLOW_SYMLINK,
|
||||
_mkdirat);
|
||||
_mkdirat, label_context);
|
||||
|
||||
if (fstatat(dir_fd, p, &st, AT_SYMLINK_NOFOLLOW) < 0)
|
||||
return -errno;
|
||||
@@ -80,20 +81,20 @@ int mkdirat_safe_internal(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mkdirat_errno_wrapper(int dirfd, const char *pathname, mode_t mode) {
|
||||
int mkdirat_errno_wrapper(int dirfd, const char *pathname, mode_t mode, LabelContext *label_context) {
|
||||
return RET_NERRNO(mkdirat(dirfd, pathname, mode));
|
||||
}
|
||||
|
||||
int mkdirat_safe(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) {
|
||||
return mkdirat_safe_internal(dir_fd, path, mode, uid, gid, flags, mkdirat_errno_wrapper);
|
||||
return mkdirat_safe_internal(dir_fd, path, mode, uid, gid, flags, mkdirat_errno_wrapper, /* label_context= */ NULL);
|
||||
}
|
||||
|
||||
int mkdirat_parents_internal(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdirat) {
|
||||
int mkdirat_parents_internal(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdirat, LabelContext *label_context) {
|
||||
const char *e = NULL;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(_mkdirat != mkdirat);
|
||||
assert(_mkdirat);
|
||||
|
||||
if (isempty(path))
|
||||
return 0;
|
||||
@@ -134,7 +135,7 @@ int mkdirat_parents_internal(int dir_fd, const char *path, mode_t mode, uid_t ui
|
||||
|
||||
s[n] = '\0';
|
||||
|
||||
r = mkdirat_safe_internal(dir_fd, path, mode, uid, gid, flags | MKDIR_IGNORE_EXISTING, _mkdirat);
|
||||
r = mkdirat_safe_internal(dir_fd, path, mode, uid, gid, flags | MKDIR_IGNORE_EXISTING, _mkdirat, label_context);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
return r;
|
||||
|
||||
@@ -142,12 +143,12 @@ int mkdirat_parents_internal(int dir_fd, const char *path, mode_t mode, uid_t ui
|
||||
}
|
||||
}
|
||||
|
||||
int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdirat) {
|
||||
int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdirat, LabelContext *label_context) {
|
||||
_cleanup_close_ int fd = AT_FDCWD;
|
||||
const char *p;
|
||||
|
||||
assert(path);
|
||||
assert(_mkdirat != mkdirat);
|
||||
assert(_mkdirat);
|
||||
|
||||
if (prefix) {
|
||||
p = path_startswith_full(path, prefix, PATH_STARTSWITH_REFUSE_DOT_DOT);
|
||||
@@ -160,34 +161,34 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui
|
||||
} else
|
||||
p = path;
|
||||
|
||||
return mkdirat_parents_internal(fd, p, mode, uid, gid, flags, _mkdirat);
|
||||
return mkdirat_parents_internal(fd, p, mode, uid, gid, flags, _mkdirat, label_context);
|
||||
}
|
||||
|
||||
int mkdirat_parents(int dir_fd, const char *path, mode_t mode) {
|
||||
return mkdirat_parents_internal(dir_fd, path, mode, UID_INVALID, UID_INVALID, 0, mkdirat_errno_wrapper);
|
||||
return mkdirat_parents_internal(dir_fd, path, mode, UID_INVALID, UID_INVALID, 0, mkdirat_errno_wrapper, /* label_context= */ NULL);
|
||||
}
|
||||
|
||||
int mkdir_parents_safe(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) {
|
||||
return mkdir_parents_internal(prefix, path, mode, uid, gid, flags, mkdirat_errno_wrapper);
|
||||
return mkdir_parents_internal(prefix, path, mode, uid, gid, flags, mkdirat_errno_wrapper, /* label_context= */ NULL);
|
||||
}
|
||||
|
||||
int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdirat) {
|
||||
int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdirat, LabelContext *label_context) {
|
||||
int r;
|
||||
|
||||
/* Like mkdir -p */
|
||||
|
||||
assert(_mkdirat != mkdirat);
|
||||
assert(_mkdirat);
|
||||
|
||||
r = mkdir_parents_internal(prefix, path, mode, uid, gid, flags | MKDIR_FOLLOW_SYMLINK, _mkdirat);
|
||||
r = mkdir_parents_internal(prefix, path, mode, uid, gid, flags | MKDIR_FOLLOW_SYMLINK, _mkdirat, label_context);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!uid_is_valid(uid) && !gid_is_valid(gid) && flags == 0) {
|
||||
r = _mkdirat(AT_FDCWD, path, mode);
|
||||
r = _mkdirat(AT_FDCWD, path, mode, label_context);
|
||||
if (r < 0 && (r != -EEXIST || is_dir(path, true) <= 0))
|
||||
return r;
|
||||
} else {
|
||||
r = mkdir_safe_internal(path, mode, uid, gid, flags, _mkdirat);
|
||||
r = mkdir_safe_internal(path, mode, uid, gid, flags, _mkdirat, label_context);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
return r;
|
||||
}
|
||||
@@ -196,11 +197,11 @@ int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t ui
|
||||
}
|
||||
|
||||
int mkdir_p(const char *path, mode_t mode) {
|
||||
return mkdir_p_internal(NULL, path, mode, UID_INVALID, UID_INVALID, 0, mkdirat_errno_wrapper);
|
||||
return mkdir_p_internal(/* prefix= */ NULL, path, mode, UID_INVALID, UID_INVALID, 0, mkdirat_errno_wrapper, /* label_context= */ NULL);
|
||||
}
|
||||
|
||||
int mkdir_p_safe(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) {
|
||||
return mkdir_p_internal(prefix, path, mode, uid, gid, flags, mkdirat_errno_wrapper);
|
||||
return mkdir_p_internal(prefix, path, mode, uid, gid, flags, mkdirat_errno_wrapper, /* label_context= */ NULL);
|
||||
}
|
||||
|
||||
int mkdir_p_root_full(const char *root, const char *p, uid_t uid, gid_t gid, mode_t m, usec_t ts, Hashmap *subvolumes) {
|
||||
|
||||
+8
-8
@@ -9,7 +9,7 @@ typedef enum MkdirFlags {
|
||||
MKDIR_WARN_MODE = 1 << 2, /* Log at LOG_WARNING when mode doesn't match */
|
||||
} MkdirFlags;
|
||||
|
||||
int mkdirat_errno_wrapper(int dirfd, const char *pathname, mode_t mode);
|
||||
int mkdirat_errno_wrapper(int dirfd, const char *pathname, mode_t mode, LabelContext *label_context);
|
||||
|
||||
int mkdirat_safe(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags);
|
||||
static inline int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) {
|
||||
@@ -28,11 +28,11 @@ static inline int mkdir_p_root(const char *root, const char *p, uid_t uid, gid_t
|
||||
}
|
||||
|
||||
/* The following are used to implement the mkdir_xyz_label() calls, don't use otherwise. */
|
||||
typedef int (*mkdirat_func_t)(int dir_fd, const char *pathname, mode_t mode);
|
||||
int mkdirat_safe_internal(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdir);
|
||||
static inline int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdir) {
|
||||
return mkdirat_safe_internal(AT_FDCWD, path, mode, uid, gid, flags, _mkdir);
|
||||
typedef int (*mkdirat_func_t)(int dir_fd, const char *pathname, mode_t mode, LabelContext *label_context);
|
||||
int mkdirat_safe_internal(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdir, LabelContext *label_context);
|
||||
static inline int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdir, LabelContext *label_context) {
|
||||
return mkdirat_safe_internal(AT_FDCWD, path, mode, uid, gid, flags, _mkdir, label_context);
|
||||
}
|
||||
int mkdirat_parents_internal(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdirat);
|
||||
int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdir);
|
||||
int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdir);
|
||||
int mkdirat_parents_internal(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdirat, LabelContext *label_context);
|
||||
int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdir, LabelContext *label_context);
|
||||
int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, mkdirat_func_t _mkdir, LabelContext *label_context);
|
||||
|
||||
Reference in New Issue
Block a user