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:
Simon de Vlieger
2026-07-31 09:49:41 +02:00
parent 63e35ca3f9
commit 6b0e3ea222
33 changed files with 192 additions and 169 deletions
+4 -4
View File
@@ -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);
}
+4 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+4 -4
View File
@@ -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 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+2 -2
View File
@@ -982,7 +982,7 @@ static int setup_credentials_plain_dir(
return log_debug_errno(dfd, "Failed to create workspace for credentials: %m");
workspace_rm = workspace;
(void) label_fix_full(dfd, /* inode_path= */ NULL, cred_dir, /* flags= */ 0);
(void) label_fix_full(dfd, /* inode_path= */ NULL, cred_dir, /* flags= */ 0, /* label_context= */ NULL);
r = acquire_credentials(context, dfd, /* ownership_ok= */ false);
if (r < 0)
@@ -1063,7 +1063,7 @@ static int setup_credentials_internal(
if (dfd < 0)
return dfd;
(void) label_fix_full(dfd, /* inode_path= */ NULL, cred_dir, /* flags= */ 0);
(void) label_fix_full(dfd, /* inode_path= */ NULL, cred_dir, /* flags= */ 0, /* label_context= */ NULL);
r = acquire_credentials(context, dfd, /* ownership_ok= */ true);
if (r < 0)
+5 -5
View File
@@ -1220,7 +1220,7 @@ static int clone_device_node(const char *node, const char *temporary_mount, bool
/* First, try to create device node properly */
if (*make_devnode) {
mac_selinux_create_file_prepare(node, st.st_mode);
mac_selinux_create_file_prepare(node, st.st_mode, /* label_context= */ NULL);
r = mknod(dn, st.st_mode, st.st_rdev);
mac_selinux_create_file_clear();
if (r >= 0)
@@ -1341,7 +1341,7 @@ static int mount_private_dev(const MountEntry *m, const NamespaceParameters *p)
if (r < 0)
return r;
r = label_fix_full(AT_FDCWD, dev, "/dev", 0);
r = label_fix_full(AT_FDCWD, dev, "/dev", /* flags= */ 0, /* label_context= */ NULL);
if (r < 0)
return log_debug_errno(r, "Failed to fix label of '%s' as /dev/: %m", dev);
@@ -1610,7 +1610,7 @@ static int mount_tmpfs(const MountEntry *m) {
if (r < 0)
return r;
r = label_fix_full(AT_FDCWD, entry_path, inner_path, 0);
r = label_fix_full(AT_FDCWD, entry_path, inner_path, /* flags= */ 0, /* label_context= */ NULL);
if (r < 0)
return log_debug_errno(r, "Failed to fix label of '%s' as '%s': %m", entry_path, inner_path);
@@ -2067,7 +2067,7 @@ static int apply_one_mount(
if (r < 0)
return log_debug_errno(r, "Failed to create source directory %s: %m", mount_entry_source(m));
r = label_fix_full(AT_FDCWD, mount_entry_source(m), mount_entry_unprefixed_path(m), /* flags= */ 0);
r = label_fix_full(AT_FDCWD, mount_entry_source(m), mount_entry_unprefixed_path(m), /* flags= */ 0, /* label_context= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to set label of the source directory %s: %m", mount_entry_source(m));
}
@@ -3474,7 +3474,7 @@ int setup_tmp_dir_one(const char *id, const char *prefix, char **ret_path) {
return r;
}
r = label_fix_full(AT_FDCWD, inner_dir, prefix, 0);
r = label_fix_full(AT_FDCWD, inner_dir, prefix, /* flags= */ 0, /* label_context= */ NULL);
if (r < 0) {
(void) rmdir(inner_dir);
(void) rmdir(d);
+1 -1
View File
@@ -1209,7 +1209,7 @@ static int fifo_address_create(
(void) mkdir_parents_label(path, directory_mode);
r = mac_selinux_create_file_prepare(path, S_IFIFO);
r = mac_selinux_create_file_prepare(path, S_IFIFO, /* label_context= */ NULL);
if (r < 0)
return r;
+2 -2
View File
@@ -1038,7 +1038,7 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch
int r;
bool found = false;
r = fopen_temporary_at_label(etc_fd, "passwd", "passwd", &passwd, &passwd_tmp);
r = fopen_temporary_at_label(etc_fd, "passwd", "passwd", &passwd, &passwd_tmp, /* label_context= */ NULL);
if (r < 0)
return r;
@@ -1109,7 +1109,7 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) {
int r;
bool found = false;
r = fopen_temporary_at_label(etc_fd, "shadow", "shadow", &shadow, &shadow_tmp);
r = fopen_temporary_at_label(etc_fd, "shadow", "shadow", &shadow, &shadow_tmp, /* label_context= */ NULL);
if (r < 0)
return r;
+5 -5
View File
@@ -480,7 +480,7 @@ static int fd_copy_symlink(
return r;
if (copy_flags & COPY_MAC_CREATE) {
r = mac_selinux_create_file_prepare_at(dt, to, S_IFLNK);
r = mac_selinux_create_file_prepare_at(dt, to, S_IFLNK, /* label_context= */ NULL);
if (r < 0)
return r;
}
@@ -836,7 +836,7 @@ static int fd_copy_regular(
return fdf;
if (copy_flags & COPY_MAC_CREATE) {
r = mac_selinux_create_file_prepare_at(dt, to, S_IFREG);
r = mac_selinux_create_file_prepare_at(dt, to, S_IFREG, /* label_context= */ NULL);
if (r < 0)
return r;
}
@@ -923,7 +923,7 @@ static int fd_copy_fifo(
return 0;
if (copy_flags & COPY_MAC_CREATE) {
r = mac_selinux_create_file_prepare_at(dt, to, S_IFIFO);
r = mac_selinux_create_file_prepare_at(dt, to, S_IFIFO, /* label_context= */ NULL);
if (r < 0)
return r;
}
@@ -976,7 +976,7 @@ static int fd_copy_node(
return 0;
if (copy_flags & COPY_MAC_CREATE) {
r = mac_selinux_create_file_prepare_at(dt, to, st->st_mode & S_IFMT);
r = mac_selinux_create_file_prepare_at(dt, to, st->st_mode & S_IFMT, /* label_context= */ NULL);
if (r < 0)
return r;
}
@@ -1577,7 +1577,7 @@ int copy_file_atomic_at_full(
assert(!FLAGS_SET(copy_flags, COPY_LOCK_BSD));
if (copy_flags & COPY_MAC_CREATE) {
r = mac_selinux_create_file_prepare_at(dir_fdt, to, S_IFREG);
r = mac_selinux_create_file_prepare_at(dir_fdt, to, S_IFREG, /* label_context= */ NULL);
if (r < 0)
return r;
}
+3 -3
View File
@@ -46,7 +46,7 @@ int dev_setup(const char *prefix, uid_t uid, gid_t gid) {
} else
n = k;
r = symlink_label(j, n);
r = symlink_label(j, n, /* label_context= */ NULL);
if (r < 0)
log_debug_errno(r, "Failed to symlink %s to %s: %m", j, n);
@@ -113,9 +113,9 @@ int make_inaccessible_nodes(
return log_oom();
if (S_ISDIR(inode_type))
r = mkdirat_label(inaccessible_fd, fn, 0000);
r = mkdirat_label(inaccessible_fd, fn, 0000, /* label_context= */ NULL);
else
r = mknodat_label(inaccessible_fd, fn, inode_type | 0000, makedev(0, 0));
r = mknodat_label(inaccessible_fd, fn, inode_type | 0000, makedev(0, 0), /* label_context= */ NULL);
if (r == -EEXIST) {
if (fchmodat(inaccessible_fd, fn, 0000, AT_SYMLINK_NOFOLLOW) < 0)
log_debug_errno(errno, "Failed to adjust access mode of existing inode '%s', ignoring: %m", path);
+1 -1
View File
@@ -2199,7 +2199,7 @@ int image_setup_pool(RuntimeScope scope, ImageClass class, bool use_btrfs_subvol
if (!use_btrfs_subvol)
return 0;
(void) btrfs_subvol_make_label(pool);
(void) btrfs_subvol_make_label(pool, /* label_context= */ NULL);
if (!use_btrfs_quota)
return 0;
+9 -8
View File
@@ -13,7 +13,8 @@ int label_fix_full(
int atfd,
const char *inode_path, /* path of inode to apply label to */
const char *label_path, /* path to use as database lookup key in label database (typically same as inode_path, but not always) */
LabelFixFlags flags) {
LabelFixFlags flags,
LabelContext *label_context) {
int r, q;
@@ -30,7 +31,7 @@ int label_fix_full(
* If atfd is AT_FDCWD then we'll operate on the inode the path refers to.
*/
r = mac_selinux_fix_full(atfd, inode_path, label_path, flags);
r = mac_selinux_fix_full(atfd, inode_path, label_path, flags, label_context);
q = mac_smack_fix_full(atfd, inode_path, label_path, flags);
if (r < 0)
return r;
@@ -40,13 +41,13 @@ int label_fix_full(
return 0;
}
int symlink_label(const char *old_path, const char *new_path) {
int symlink_label(const char *old_path, const char *new_path, LabelContext *label_context) {
int r;
assert(old_path);
assert(new_path);
r = mac_selinux_create_file_prepare(new_path, S_IFLNK);
r = mac_selinux_create_file_prepare(new_path, S_IFLNK, label_context);
if (r < 0)
return r;
@@ -59,13 +60,13 @@ int symlink_label(const char *old_path, const char *new_path) {
return mac_smack_fix(new_path, 0);
}
int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev) {
int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev, LabelContext *label_context) {
int r;
assert(dirfd >= 0 || dirfd == AT_FDCWD);
assert(pathname);
r = mac_selinux_create_file_prepare_at(dirfd, pathname, mode);
r = mac_selinux_create_file_prepare_at(dirfd, pathname, mode, label_context);
if (r < 0)
return r;
@@ -78,12 +79,12 @@ int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev) {
return mac_smack_fix_full(dirfd, pathname, NULL, 0);
}
int btrfs_subvol_make_label(const char *path) {
int btrfs_subvol_make_label(const char *path, LabelContext *label_context) {
int r;
assert(path);
r = mac_selinux_create_file_prepare(path, S_IFDIR);
r = mac_selinux_create_file_prepare(path, S_IFDIR, label_context);
if (r < 0)
return r;
+6 -6
View File
@@ -10,20 +10,20 @@ typedef enum LabelFixFlags {
LABEL_IGNORE_EROFS = 1 << 1,
} LabelFixFlags;
int label_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags);
int label_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags, LabelContext *label_context);
static inline int label_fix(const char *path, LabelFixFlags flags) {
return label_fix_full(AT_FDCWD, path, path, flags);
return label_fix_full(AT_FDCWD, path, path, flags, /* label_context= */ NULL);
}
int symlink_label(const char *old_path, const char *new_path);
int symlink_label(const char *old_path, const char *new_path, LabelContext *label_context);
int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev);
int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev, LabelContext *label_context);
static inline int mknod_label(const char *pathname, mode_t mode, dev_t dev) {
return mknodat_label(AT_FDCWD, pathname, mode, dev);
return mknodat_label(AT_FDCWD, pathname, mode, dev, /* label_context= */ NULL);
}
int btrfs_subvol_make_label(const char *path);
int btrfs_subvol_make_label(const char *path, LabelContext *label_context);
int mac_init(void);
int mac_init_lazy(void);
+6 -14
View File
@@ -8,12 +8,12 @@
#include "selinux-util.h"
#include "smack-util.h"
int mkdirat_label(int dirfd, const char *path, mode_t mode) {
int mkdirat_label(int dirfd, const char *path, mode_t mode, LabelContext *label_context) {
int r;
assert(path);
r = mac_selinux_create_file_prepare_at(dirfd, path, S_IFDIR);
r = mac_selinux_create_file_prepare_at(dirfd, path, S_IFDIR, label_context);
if (r < 0)
return r;
@@ -25,18 +25,10 @@ int mkdirat_label(int dirfd, const char *path, mode_t mode) {
return mac_smack_fix_full(dirfd, path, NULL, 0);
}
int mkdirat_safe_label(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_label);
int mkdirat_safe_label(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, LabelContext *label_context) {
return mkdirat_safe_internal(dir_fd, path, mode, uid, gid, flags, mkdirat_label, label_context);
}
int mkdirat_parents_label(int dir_fd, const char *path, mode_t mode) {
return mkdirat_parents_internal(dir_fd, path, mode, UID_INVALID, UID_INVALID, 0, mkdirat_label);
}
int mkdir_parents_safe_label(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_label);
}
int mkdir_p_label(const char *path, mode_t mode) {
return mkdir_p_internal(NULL, path, mode, UID_INVALID, UID_INVALID, 0, mkdirat_label);
int mkdirat_parents_label(int dir_fd, const char *path, mode_t mode, LabelContext *label_context) {
return mkdirat_parents_internal(dir_fd, path, mode, UID_INVALID, UID_INVALID, 0, mkdirat_label, label_context);
}
+12 -8
View File
@@ -5,21 +5,25 @@
#include "../basic/mkdir.h" /* IWYU pragma: export */
int mkdirat_label(int dirfd, const char *path, mode_t mode);
int mkdirat_label(int dirfd, const char *path, mode_t mode, LabelContext *label_context);
static inline int mkdir_label(const char *path, mode_t mode) {
return mkdirat_label(AT_FDCWD, path, mode);
return mkdirat_label(AT_FDCWD, path, mode, /* label_context= */ NULL);
}
int mkdirat_safe_label(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags);
int mkdirat_safe_label(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags, LabelContext *label_context);
static inline int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags) {
return mkdirat_safe_label(AT_FDCWD, path, mode, uid, gid, flags);
return mkdirat_safe_label(AT_FDCWD, path, mode, uid, gid, flags, /* label_context= */ NULL);
}
int mkdirat_parents_label(int dir_fd, const char *path, mode_t mod);
int mkdirat_parents_label(int dir_fd, const char *path, mode_t mod, LabelContext *label_context);
static inline int mkdir_parents_label(const char *path, mode_t mod) {
return mkdirat_parents_label(AT_FDCWD, path, mod);
return mkdirat_parents_label(AT_FDCWD, path, mod, /* label_context= */ NULL);
}
int mkdir_parents_safe_label(const char *prefix, const char *path, mode_t mode, uid_t uid, gid_t gid, MkdirFlags flags);
static inline int mkdir_parents_safe_label(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_label, /* label_context= */ NULL);
}
int mkdir_p_label(const char *path, mode_t mode);
static inline int mkdir_p_label(const char *path, mode_t mode) {
return mkdir_p_internal(/* prefix= */ NULL, path, mode, UID_INVALID, UID_INVALID, 0, mkdirat_label, /* label_context= */ NULL);
}
+1 -1
View File
@@ -1946,7 +1946,7 @@ int make_mount_point_inode_from_mode(int dir_fd, const char *dest, mode_t source
assert(dest);
if (S_ISDIR(source_mode))
return mkdirat_label(dir_fd, dest, target_mode & 07777);
return mkdirat_label(dir_fd, dest, target_mode & 07777, /* label_context= */ NULL);
else
return RET_NERRNO(mknodat(dir_fd, dest, S_IFREG|(target_mode & 07666), 0)); /* Mask off X bit */
}
+7 -5
View File
@@ -43,11 +43,11 @@ static int last_policyload = 0;
static struct selabel_handle *label_hnd = NULL;
static bool have_status_page = false;
static int mac_selinux_label_pre(int dir_fd, const char *path, mode_t mode) {
return mac_selinux_create_file_prepare_at(dir_fd, path, mode);
static int mac_selinux_label_pre(int dir_fd, const char *path, mode_t mode, LabelContext *label_context) {
return mac_selinux_create_file_prepare_at(dir_fd, path, mode, label_context);
}
static int mac_selinux_label_post(int dir_fd, const char *path, bool created) {
static int mac_selinux_label_post(int dir_fd, const char *path, bool created, LabelContext *label_context) {
mac_selinux_create_file_clear();
return 0;
}
@@ -421,7 +421,8 @@ int mac_selinux_fix_full(
int atfd,
const char *inode_path,
const char *label_path,
LabelFixFlags flags) {
LabelFixFlags flags,
LabelContext *label_context) {
assert(atfd >= 0 || atfd == AT_FDCWD);
assert(atfd >= 0 || inode_path);
@@ -694,7 +695,8 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
int mac_selinux_create_file_prepare_at(
int dir_fd,
const char *path,
mode_t mode) {
mode_t mode,
LabelContext *label_context) {
#if HAVE_SELINUX
_cleanup_free_ char *abspath = NULL;
+4 -4
View File
@@ -93,7 +93,7 @@ void mac_selinux_finish(void);
void mac_selinux_disable_logging(void);
int mac_selinux_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags);
int mac_selinux_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags, LabelContext *label_context);
int mac_selinux_apply(const char *path, const char *label);
int mac_selinux_apply_fd(int fd, const char *path, const char *label);
@@ -103,9 +103,9 @@ int mac_selinux_get_our_label(char **ret_label);
int mac_selinux_get_peer_label(int socket_fd, char **ret_label);
int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **ret_label);
int mac_selinux_create_file_prepare_at(int dir_fd, const char *path, mode_t mode);
static inline int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
return mac_selinux_create_file_prepare_at(AT_FDCWD, path, mode);
int mac_selinux_create_file_prepare_at(int dir_fd, const char *path, mode_t mode, LabelContext *label_context);
static inline int mac_selinux_create_file_prepare(const char *path, mode_t mode, LabelContext *label_context) {
return mac_selinux_create_file_prepare_at(AT_FDCWD, path, mode, label_context);
}
int mac_selinux_create_file_prepare_label(const char *path, const char *label);
void mac_selinux_create_file_clear(void);
+2 -2
View File
@@ -221,11 +221,11 @@ int renameat_and_apply_smack_floor_label(int fdf, const char *from, int fdt, con
#endif
}
static int mac_smack_label_pre(int dir_fd, const char *path, mode_t mode) {
static int mac_smack_label_pre(int dir_fd, const char *path, mode_t mode, LabelContext *label_context) {
return 0;
}
static int mac_smack_label_post(int dir_fd, const char *path, bool created) {
static int mac_smack_label_post(int dir_fd, const char *path, bool created, LabelContext *label_context) {
if (!created)
return 0;
+3 -2
View File
@@ -10,14 +10,15 @@ int fopen_temporary_at_label(
const char *target,
const char *path,
FILE **f,
char **temp_path) {
char **temp_path,
LabelContext *label_context) {
int r;
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
r = mac_selinux_create_file_prepare_at(dir_fd, target, S_IFREG);
r = mac_selinux_create_file_prepare_at(dir_fd, target, S_IFREG, label_context);
if (r < 0)
return r;
+2 -2
View File
@@ -7,7 +7,7 @@
* Targets that link libshared automatically pick up this version via -Isrc/shared; targets that only have
* src/basic on their include path fall through to the basic header. */
int fopen_temporary_at_label(int dir_fd, const char *target, const char *path, FILE **f, char **temp_path);
int fopen_temporary_at_label(int dir_fd, const char *target, const char *path, FILE **f, char **temp_path, LabelContext *label_context);
static inline int fopen_temporary_label(const char *target, const char *path, FILE **f, char **temp_path) {
return fopen_temporary_at_label(AT_FDCWD, target, path, f, temp_path);
return fopen_temporary_at_label(AT_FDCWD, target, path, f, temp_path, /* label_context= */ NULL);
}
+4 -4
View File
@@ -998,7 +998,7 @@ static int resolve_mutable_directory(
if (fchmod(chmod_fd, hierarchy_mode) < 0)
return log_error_errno(errno, "Failed to chmod directory '%s/%s': %m", strempty(root), skip_leading_slash(path));
r = mac_selinux_fix_full(chmod_fd, /* inode_path= */ NULL, hierarchy, /* flags= */ 0);
r = mac_selinux_fix_full(chmod_fd, /* inode_path= */ NULL, hierarchy, /* flags= */ 0, /* label_context= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to fix SELinux label for '%s/%s': %m", strempty(root), skip_leading_slash(path));
}
@@ -1376,7 +1376,7 @@ static int mount_overlayfs_with_op(
if (atfd < 0)
return log_error_errno(errno, "Failed to open directory '%s': %m", meta_path);
r = mac_selinux_fix_full(atfd, /* inode_path= */ NULL, op->hierarchy, /* flags= */ 0);
r = mac_selinux_fix_full(atfd, /* inode_path= */ NULL, op->hierarchy, /* flags= */ 0, /* label_context= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to fix SELinux label for '%s': %m", meta_path);
@@ -1389,7 +1389,7 @@ static int mount_overlayfs_with_op(
if (dfd < 0)
return log_error_errno(errno, "Failed to open directory '%s': %m", op->work_dir);
r = mac_selinux_fix_full(dfd, /* inode_path= */ NULL, op->hierarchy, /* flags= */ 0);
r = mac_selinux_fix_full(dfd, /* inode_path= */ NULL, op->hierarchy, /* flags= */ 0, /* label_context= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to fix SELinux label for '%s': %m", op->work_dir);
@@ -1601,7 +1601,7 @@ static int store_info_in_meta(
if (atfd < 0)
return log_error_errno(errno, "Failed to open directory '%s': %m", f);
r = mac_selinux_fix_full(atfd, /* inode_path= */ NULL, hierarchy, /* flags= */ 0);
r = mac_selinux_fix_full(atfd, /* inode_path= */ NULL, hierarchy, /* flags= */ 0, /* label_context= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to fix SELinux label for '%s': %m", hierarchy);
+13 -13
View File
@@ -30,7 +30,7 @@ static int check_path(int dir_fd, const char *path) {
return 0;
}
static int pre_labelling_func(int dir_fd, const char *path, mode_t mode) {
static int pre_labelling_func(int dir_fd, const char *path, mode_t mode, LabelContext *label_context) {
int r;
assert(mode != MODE_INVALID);
@@ -41,7 +41,7 @@ static int pre_labelling_func(int dir_fd, const char *path, mode_t mode) {
return 0;
}
static int post_labelling_func(int dir_fd, const char *path, bool created) {
static int post_labelling_func(int dir_fd, const char *path, bool created, LabelContext *label_context) {
int r;
/* assume label policies that restrict certain labels */
@@ -115,11 +115,11 @@ TEST(label_ops_pre) {
label_ops_reset();
label_ops_set(&test_label_ops);
fd = get_dir_fd("file1.txt", 0755);
assert_se(label_ops_pre(fd, "file1.txt", 0644) == 0);
assert_se(label_ops_pre(fd, "/restricted_directory", 0644) == -EACCES);
assert_se(label_ops_pre(fd, "", 0700) == -EINVAL);
assert_se(label_ops_pre(fd, "/tmp", 0700) == 0);
assert_se(label_ops_pre(fd, "wekrgoierhgoierhqgherhgwklegnlweehgorwfkryrit", 0644) == -ENAMETOOLONG);
assert_se(label_ops_pre(fd, "file1.txt", 0644, /* label_context= */ NULL) == 0);
assert_se(label_ops_pre(fd, "/restricted_directory", 0644, /* label_context= */ NULL) == -EACCES);
assert_se(label_ops_pre(fd, "", 0700, /* label_context= */ NULL) == -EINVAL);
assert_se(label_ops_pre(fd, "/tmp", 0700, /* label_context= */ NULL) == 0);
assert_se(label_ops_pre(fd, "wekrgoierhgoierhqgherhgwklegnlweehgorwfkryrit", 0644, /* label_context= */ NULL) == -ENAMETOOLONG);
}
TEST(label_ops_post) {
@@ -138,17 +138,17 @@ TEST(label_ops_post) {
text1 = "Add initial texts to file for testing label operations to file1\n";
assert_se(labelling_op(fd, text1, "file1.txt", 0644) == 0);
assert_se(label_ops_post(fd, "file1.txt", true) == 0);
assert_se(label_ops_post(fd, "file1.txt", true, /* label_context= */ NULL) == 0);
assert_se(strlen(text1) == (size_t)buf.st_size);
text2 = "Add text2 data to file2\n";
assert_se(labelling_op(fd, text2, "file2.txt", 0644) == 0);
assert_se(label_ops_post(fd, "file2.txt", true) == 0);
assert_se(label_ops_post(fd, "file2.txt", true, /* label_context= */ NULL) == 0);
assert_se(strlen(text2) == (size_t)buf.st_size);
assert_se(label_ops_post(fd, "file3.txt", true) == -ENOENT);
assert_se(label_ops_post(fd, "/abcd", true) == -ENOENT);
assert_se(label_ops_post(fd, "/restricted_directory", true) == -EACCES);
assert_se(label_ops_post(fd, "", true) == -EINVAL);
assert_se(label_ops_post(fd, "file3.txt", true, /* label_context= */ NULL) == -ENOENT);
assert_se(label_ops_post(fd, "/abcd", true, /* label_context= */ NULL) == -ENOENT);
assert_se(label_ops_post(fd, "/restricted_directory", true, /* label_context= */ NULL) == -EACCES);
assert_se(label_ops_post(fd, "", true, /* label_context= */ NULL) == -EINVAL);
}
DEFINE_TEST_MAIN(LOG_INFO)
+1 -1
View File
@@ -84,7 +84,7 @@ static void test_create_file_prepare(const char* fname) {
log_info("============ %s ==========", __func__);
r = mac_selinux_create_file_prepare(fname, S_IRWXU);
r = mac_selinux_create_file_prepare(fname, S_IRWXU, /* label_context= */ NULL);
log_info_errno(r, "mac_selinux_create_file_prepare → %d (%m)", r);
mac_selinux_create_file_clear();
+12 -12
View File
@@ -1062,7 +1062,7 @@ shortcut:
}
log_debug("Relabelling \"%s\"", path);
return label_fix_full(fd, /* inode_path= */ NULL, /* label_path= */ path, 0);
return label_fix_full(fd, /* inode_path= */ NULL, /* label_path= */ path, /* flags= */ 0, /* label_context= */ NULL);
}
static int path_open_parent_safe(const char *path, bool allow_failure) {
@@ -2070,7 +2070,7 @@ static int create_file(
return dir_fd;
WITH_UMASK(0000) {
mac_selinux_create_file_prepare(path, S_IFREG);
mac_selinux_create_file_prepare(path, S_IFREG, /* label_context= */ NULL);
fd = RET_NERRNO(openat(dir_fd, bn, O_CREAT|O_EXCL|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode));
mac_selinux_create_file_clear();
}
@@ -2153,7 +2153,7 @@ static int truncate_file(
creation = CREATION_NORMAL; /* Didn't work without O_CREATE, try again with */
WITH_UMASK(0000) {
mac_selinux_create_file_prepare(path, S_IFREG);
mac_selinux_create_file_prepare(path, S_IFREG, /* label_context= */ NULL);
fd = RET_NERRNO(openat(dir_fd, bn, O_CREAT|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode));
mac_selinux_create_file_clear();
}
@@ -2314,7 +2314,7 @@ static int create_directory_or_subvolume(
log_action("Would create", "Creating", "%s directory \"%s\"", path);
if (!arg_dry_run)
WITH_UMASK(0000)
r = mkdirat_label(pfd, bn, mode);
r = mkdirat_label(pfd, bn, mode, /* label_context= */ NULL);
}
if (arg_dry_run)
@@ -2501,7 +2501,7 @@ static int create_device(
return dfd;
WITH_UMASK(0000) {
mac_selinux_create_file_prepare(i->path, file_type);
mac_selinux_create_file_prepare(i->path, file_type, /* label_context= */ NULL);
r = RET_NERRNO(mknodat(dfd, bn, i->mode | file_type, i->major_minor));
mac_selinux_create_file_clear();
}
@@ -2532,7 +2532,7 @@ static int create_device(
fd = safe_close(fd);
WITH_UMASK(0000) {
mac_selinux_create_file_prepare(i->path, file_type);
mac_selinux_create_file_prepare(i->path, file_type, /* label_context= */ NULL);
r = mknodat_atomic(dfd, bn, i->mode | file_type, i->major_minor);
mac_selinux_create_file_clear();
}
@@ -2543,7 +2543,7 @@ static int create_device(
if (r < 0)
return log_error_errno(r, "rm -rf %s failed: %m", i->path);
mac_selinux_create_file_prepare(i->path, file_type);
mac_selinux_create_file_prepare(i->path, file_type, /* label_context= */ NULL);
r = RET_NERRNO(mknodat(dfd, bn, i->mode | file_type, i->major_minor));
mac_selinux_create_file_clear();
}
@@ -2611,7 +2611,7 @@ static int create_fifo(Context *c, Item *i) {
return pfd;
WITH_UMASK(0000) {
mac_selinux_create_file_prepare(i->path, S_IFIFO);
mac_selinux_create_file_prepare(i->path, S_IFIFO, /* label_context= */ NULL);
r = RET_NERRNO(mkfifoat(pfd, bn, i->mode));
mac_selinux_create_file_clear();
}
@@ -2636,7 +2636,7 @@ static int create_fifo(Context *c, Item *i) {
fd = safe_close(fd);
WITH_UMASK(0000) {
mac_selinux_create_file_prepare(i->path, S_IFIFO);
mac_selinux_create_file_prepare(i->path, S_IFIFO, /* label_context= */ NULL);
r = mkfifoat_atomic(pfd, bn, i->mode);
mac_selinux_create_file_clear();
}
@@ -2645,7 +2645,7 @@ static int create_fifo(Context *c, Item *i) {
if (r < 0)
return log_error_errno(r, "rm -rf %s failed: %m", i->path);
mac_selinux_create_file_prepare(i->path, S_IFIFO);
mac_selinux_create_file_prepare(i->path, S_IFIFO, /* label_context= */ NULL);
r = RET_NERRNO(mkfifoat(pfd, bn, i->mode));
mac_selinux_create_file_clear();
}
@@ -2730,7 +2730,7 @@ static int create_symlink(Context *c, Item *i) {
if (pfd < 0)
return pfd;
mac_selinux_create_file_prepare(i->path, S_IFLNK);
mac_selinux_create_file_prepare(i->path, S_IFLNK, /* label_context= */ NULL);
r = RET_NERRNO(symlinkat(i->argument, pfd, bn));
mac_selinux_create_file_clear();
@@ -3060,7 +3060,7 @@ static int mkdir_parents_rm_if_wrong_type(mode_t child_mode, const char *path) {
if (r == -ENOENT) {
if (!arg_dry_run) {
WITH_UMASK(0000)
r = mkdirat_label(parent_fd, t, 0755);
r = mkdirat_label(parent_fd, t, 0755, /* label_context= */ NULL);
if (r < 0) {
_cleanup_free_ char *parent_name = NULL;
+1 -1
View File
@@ -683,7 +683,7 @@ static int udev_node_apply_permissions_impl(
/* set the defaults */
if (!selinux)
(void) mac_selinux_fix_full(node_fd, NULL, devnode, LABEL_IGNORE_ENOENT);
(void) mac_selinux_fix_full(node_fd, NULL, devnode, LABEL_IGNORE_ENOENT, /* label_context= */ NULL);
if (!smack)
(void) mac_smack_apply_fd(node_fd, SMACK_ATTR_ACCESS, NULL);
}