Plumbing to perform SELinux checks in varlink API (#38146)
This PR does minimal changes to introduce varlink support. Ideally, the code should switch to using `mac_selinux_get_our_label()` and new `mac_selinux_get_peer_label()`. But I leave it for now to minimize breakage. `mac_selinux_get_peer_label()` remains unused. This is a prep step to merge https://github.com/systemd/systemd/pull/38032
This commit is contained in:
+164
-38
@@ -9,6 +9,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "audit-fd.h"
|
||||
@@ -26,6 +27,7 @@ static bool initialized = false;
|
||||
|
||||
struct audit_info {
|
||||
sd_bus_creds *creds;
|
||||
sd_varlink *link;
|
||||
const char *path;
|
||||
const char *cmdline;
|
||||
const char *function;
|
||||
@@ -48,12 +50,23 @@ static int audit_callback(
|
||||
char uid_buf[DECIMAL_STR_MAX(uid_t) + 1] = "n/a";
|
||||
char gid_buf[DECIMAL_STR_MAX(gid_t) + 1] = "n/a";
|
||||
|
||||
if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0)
|
||||
xsprintf(login_uid_buf, UID_FMT, login_uid);
|
||||
if (sd_bus_creds_get_euid(audit->creds, &uid) >= 0)
|
||||
xsprintf(uid_buf, UID_FMT, uid);
|
||||
if (sd_bus_creds_get_egid(audit->creds, &gid) >= 0)
|
||||
xsprintf(gid_buf, GID_FMT, gid);
|
||||
if (audit->creds) {
|
||||
/* DBus case */
|
||||
if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0)
|
||||
xsprintf(login_uid_buf, UID_FMT, login_uid);
|
||||
if (sd_bus_creds_get_euid(audit->creds, &uid) >= 0)
|
||||
xsprintf(uid_buf, UID_FMT, uid);
|
||||
if (sd_bus_creds_get_egid(audit->creds, &gid) >= 0)
|
||||
xsprintf(gid_buf, GID_FMT, gid);
|
||||
}
|
||||
|
||||
if (audit->link) {
|
||||
/* varlink */
|
||||
if (sd_varlink_get_peer_uid(audit->link, &uid) >= 0)
|
||||
xsprintf(uid_buf, UID_FMT, uid);
|
||||
if (sd_varlink_get_peer_gid(audit->link, &gid) >= 0)
|
||||
xsprintf(gid_buf, GID_FMT, gid);
|
||||
}
|
||||
|
||||
(void) snprintf(msgbuf, msgbufsize,
|
||||
"auid=%s uid=%s gid=%s%s%s%s%s%s%s%s%s%s",
|
||||
@@ -164,13 +177,84 @@ static int access_init(sd_bus_error *error) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int get_our_contexts(const Unit *unit, const char **ret_acon, const char **ret_tclass, char **ret_fcon) {
|
||||
_cleanup_freecon_ char *fcon = NULL;
|
||||
|
||||
assert(ret_acon);
|
||||
assert(ret_tclass);
|
||||
assert(ret_fcon);
|
||||
|
||||
if (unit && unit->access_selinux_context) {
|
||||
/* Nice! The unit comes with a SELinux context read from the unit file */
|
||||
*ret_acon = unit->access_selinux_context;
|
||||
*ret_tclass = "service";
|
||||
*ret_fcon = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If no unit context is known, use our own */
|
||||
|
||||
/* Ideally, we should call mac_selinux_get_our_label() here because it
|
||||
* does exactly the same - call getcon_raw(). However, it involves
|
||||
* selinux_init() which opens label DB. It was not part of the
|
||||
* original code. I don't want to change it for now. */
|
||||
if (getcon_raw(&fcon) < 0)
|
||||
return log_debug_errno(errno, "SELinux getcon_raw() failed: %m");
|
||||
|
||||
if (!fcon)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "SELinux returned no context of the current process");
|
||||
|
||||
*ret_acon = fcon;
|
||||
*ret_tclass = "system";
|
||||
*ret_fcon = TAKE_PTR(fcon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_access(
|
||||
const char *scon,
|
||||
const char *tcon,
|
||||
const char *tclass,
|
||||
const char *permission,
|
||||
struct audit_info *audit_info,
|
||||
sd_bus_error *error) {
|
||||
bool enforce = mac_selinux_enforcing();
|
||||
int r;
|
||||
|
||||
assert(scon);
|
||||
assert(tcon);
|
||||
assert(tclass);
|
||||
assert(permission);
|
||||
assert(audit_info);
|
||||
assert(audit_info->function);
|
||||
|
||||
r = selinux_check_access(scon, tcon, tclass, permission, &audit_info);
|
||||
if (r < 0) {
|
||||
errno = -(r = errno_or_else(EPERM));
|
||||
|
||||
if (enforce)
|
||||
sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access: %m");
|
||||
}
|
||||
|
||||
return log_selinux_enforcing_errno(
|
||||
r,
|
||||
"SELinux access check scon=%s tcon=%s tclass=%s perm=%s state=%s function=%s path=%s cmdline=%s: %m",
|
||||
scon,
|
||||
tcon,
|
||||
tclass,
|
||||
permission,
|
||||
enforce ? "enforcing" : "permissive",
|
||||
audit_info->function,
|
||||
empty_to_na(audit_info->path),
|
||||
empty_to_na(audit_info->cmdline));
|
||||
}
|
||||
|
||||
/*
|
||||
This function communicates with the kernel to check whether or not it should
|
||||
allow the access.
|
||||
If the machine is in permissive mode it will return ok. Audit messages will
|
||||
still be generated if the access would be denied in enforcing mode.
|
||||
*/
|
||||
int mac_selinux_access_check_internal(
|
||||
int mac_selinux_access_check_bus_internal(
|
||||
sd_bus_message *message,
|
||||
const Unit *unit,
|
||||
const char *permission,
|
||||
@@ -216,30 +300,21 @@ int mac_selinux_access_check_internal(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (unit && unit->access_selinux_context) {
|
||||
/* Nice! The unit comes with a SELinux context read from the unit file */
|
||||
acon = unit->access_selinux_context;
|
||||
tclass = "service";
|
||||
} else {
|
||||
/* If no unit context is known, use our own */
|
||||
if (getcon_raw(&fcon) < 0) {
|
||||
log_warning_errno(errno, "SELinux getcon_raw() failed%s (perm=%s): %m",
|
||||
enforce ? "" : ", ignoring",
|
||||
permission);
|
||||
if (!enforce)
|
||||
return 0;
|
||||
r = get_our_contexts(unit, &acon, &tclass, &fcon);
|
||||
if (r < 0) {
|
||||
log_selinux_enforcing_errno(
|
||||
r,
|
||||
"Failed to retrieves SELinux context of current process (perm=%s)%s: %m",
|
||||
permission,
|
||||
enforce ? "" : ", ignoring");
|
||||
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context: %m");
|
||||
}
|
||||
if (!fcon) {
|
||||
if (!enforce)
|
||||
return 0;
|
||||
if (!enforce)
|
||||
return 0;
|
||||
|
||||
if (r == -EOPNOTSUPP)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "We appear not to have any SELinux context: %m");
|
||||
}
|
||||
|
||||
acon = fcon;
|
||||
tclass = "system";
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context: %m");
|
||||
}
|
||||
|
||||
(void) sd_bus_creds_get_cmdline(creds, &cmdline);
|
||||
@@ -252,23 +327,66 @@ int mac_selinux_access_check_internal(
|
||||
.function = function,
|
||||
};
|
||||
|
||||
r = selinux_check_access(scon, acon, tclass, permission, &audit_info);
|
||||
if (r < 0) {
|
||||
errno = -(r = errno_or_else(EPERM));
|
||||
return check_access(scon, acon, tclass, permission, &audit_info, error);
|
||||
}
|
||||
|
||||
if (enforce)
|
||||
sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access: %m");
|
||||
}
|
||||
int mac_selinux_access_check_varlink_internal(
|
||||
sd_varlink *link,
|
||||
const Unit *unit,
|
||||
const char *permission,
|
||||
const char *function) {
|
||||
_cleanup_freecon_ char *fcon = NULL, *scon = NULL;
|
||||
const char *tclass, *acon;
|
||||
int r;
|
||||
|
||||
log_full_errno_zerook(LOG_DEBUG, r,
|
||||
"SELinux access check scon=%s tcon=%s tclass=%s perm=%s state=%s function=%s path=%s cmdline=%s: %m",
|
||||
scon, acon, tclass, permission, enforce ? "enforcing" : "permissive", function, strna(unit ? unit->fragment_path : NULL), empty_to_na(cl));
|
||||
return enforce ? r : 0;
|
||||
assert(link);
|
||||
assert(permission);
|
||||
assert(function);
|
||||
|
||||
r = access_init(/* error= */ NULL);
|
||||
if (r <= 0)
|
||||
return log_debug_errno(r, "Failed to init SELinux: %m");
|
||||
|
||||
/* delay call until we checked in `access_init()` if SELinux is actually enabled */
|
||||
bool enforce = mac_selinux_enforcing();
|
||||
|
||||
int fd = sd_varlink_get_fd(link);
|
||||
if (fd < 0)
|
||||
return log_debug_errno(fd, "Failed to get varlink peer fd: %m");
|
||||
|
||||
/* We should call mac_selinux_get_peer_label() here similarly to get_our_contexts().
|
||||
* See the explanation there why not. */
|
||||
if (getpeercon_raw(fd, &scon) < 0)
|
||||
return log_selinux_enforcing_errno(
|
||||
errno,
|
||||
"Failed to get peer SELinux context%s: %m",
|
||||
enforce ? "" : ", ignoring");
|
||||
|
||||
if (!scon)
|
||||
return log_selinux_enforcing_errno(
|
||||
SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Peer does not have SELinux context");
|
||||
|
||||
r = get_our_contexts(unit, &acon, &tclass, &fcon);
|
||||
if (r < 0)
|
||||
return log_selinux_enforcing_errno(
|
||||
r,
|
||||
"Failed to retrieves SELinux context of current process (perm=%s)%s: %m",
|
||||
permission,
|
||||
enforce ? "" : ", ignoring");
|
||||
|
||||
struct audit_info audit_info = {
|
||||
.link = link,
|
||||
.path = unit ? unit->fragment_path : NULL,
|
||||
.function = function,
|
||||
};
|
||||
|
||||
return check_access(scon, acon, tclass, permission, &audit_info, /* error= */ NULL);
|
||||
}
|
||||
|
||||
#else /* HAVE_SELINUX */
|
||||
|
||||
int mac_selinux_access_check_internal(
|
||||
int mac_selinux_access_check_bus_internal(
|
||||
sd_bus_message *message,
|
||||
const Unit *unit,
|
||||
const char *permission,
|
||||
@@ -278,4 +396,12 @@ int mac_selinux_access_check_internal(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mac_selinux_access_check_varlink_internal(
|
||||
sd_varlink *link,
|
||||
const Unit *unit,
|
||||
const char *permission,
|
||||
const char *function) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_SELINUX */
|
||||
|
||||
@@ -3,10 +3,17 @@
|
||||
|
||||
#include "core-forward.h"
|
||||
|
||||
int mac_selinux_access_check_internal(sd_bus_message *message, const Unit *unit, const char *permission, const char *function, sd_bus_error *error);
|
||||
int mac_selinux_access_check_bus_internal(sd_bus_message *message, const Unit *unit, const char *permission, const char *function, sd_bus_error *error);
|
||||
int mac_selinux_access_check_varlink_internal(sd_varlink *link, const Unit *unit, const char *permission, const char *function);
|
||||
|
||||
#define mac_selinux_access_check(message, permission, error) \
|
||||
mac_selinux_access_check_internal((message), NULL, (permission), __func__, (error))
|
||||
mac_selinux_access_check_bus_internal((message), NULL, (permission), __func__, (error))
|
||||
|
||||
#define mac_selinux_unit_access_check(unit, message, permission, error) \
|
||||
mac_selinux_access_check_internal((message), (unit), (permission), __func__, (error))
|
||||
mac_selinux_access_check_bus_internal((message), (unit), (permission), __func__, (error))
|
||||
|
||||
#define mac_selinux_access_check_varlink(link, permission) \
|
||||
mac_selinux_access_check_varlink_internal((link), NULL, (permission), __func__)
|
||||
|
||||
#define mac_selinux_unit_access_check_varlink(unit, link, permission) \
|
||||
mac_selinux_access_check_bus_internal((link), (unit), (permission), __func__)
|
||||
|
||||
+38
-27
@@ -41,21 +41,6 @@ static int last_policyload = 0;
|
||||
static struct selabel_handle *label_hnd = NULL;
|
||||
static bool have_status_page = false;
|
||||
|
||||
#define log_enforcing(...) \
|
||||
log_full(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, __VA_ARGS__)
|
||||
|
||||
#define log_enforcing_errno(error, ...) \
|
||||
({ \
|
||||
bool _enforcing = mac_selinux_enforcing(); \
|
||||
int _level = _enforcing ? LOG_ERR : LOG_WARNING; \
|
||||
int _e = (error); \
|
||||
\
|
||||
int _r = (log_get_max_level() >= LOG_PRI(_level)) \
|
||||
? log_internal(_level, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
|
||||
: -ERRNO_VALUE(_e); \
|
||||
_enforcing ? _r : 0; \
|
||||
})
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -115,7 +100,7 @@ static int open_label_db(void) {
|
||||
|
||||
hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
||||
if (!hnd)
|
||||
return log_enforcing_errno(errno, "Failed to initialize SELinux labeling handle: %m");
|
||||
return log_selinux_enforcing_errno(errno, "Failed to initialize SELinux labeling handle: %m");
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
after_timestamp = now(CLOCK_MONOTONIC);
|
||||
@@ -160,7 +145,7 @@ static int selinux_init(bool force) {
|
||||
r = selinux_status_open(/* netlink fallback= */ 1);
|
||||
if (r < 0) {
|
||||
if (!ERRNO_IS_PRIVILEGE(errno))
|
||||
return log_enforcing_errno(errno, "Failed to open SELinux status page: %m");
|
||||
return log_selinux_enforcing_errno(errno, "Failed to open SELinux status page: %m");
|
||||
log_warning_errno(errno, "selinux_status_open() with netlink fallback failed, not checking for policy reloads: %m");
|
||||
} else if (r == 1)
|
||||
log_warning("selinux_status_open() failed to open the status page, using the netlink fallback.");
|
||||
@@ -294,7 +279,7 @@ static int selinux_fix_fd(
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
return log_enforcing_errno(errno, "Unable to lookup intended SELinux security context of %s: %m", label_path);
|
||||
return log_selinux_enforcing_errno(errno, "Unable to lookup intended SELinux security context of %s: %m", label_path);
|
||||
}
|
||||
|
||||
if (setfilecon_raw(FORMAT_PROC_FD_PATH(fd), fcon) < 0) {
|
||||
@@ -314,7 +299,7 @@ static int selinux_fix_fd(
|
||||
if (getfilecon_raw(FORMAT_PROC_FD_PATH(fd), &oldcon) >= 0 && streq_ptr(fcon, oldcon))
|
||||
return 0;
|
||||
|
||||
return log_enforcing_errno(r, "Unable to fix SELinux security context of %s: %m", label_path);
|
||||
return log_selinux_enforcing_errno(r, "Unable to fix SELinux security context of %s: %m", label_path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -387,7 +372,7 @@ int mac_selinux_apply(const char *path, const char *label) {
|
||||
assert(label);
|
||||
|
||||
if (setfilecon(path, label) < 0)
|
||||
return log_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
|
||||
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -406,7 +391,7 @@ int mac_selinux_apply_fd(int fd, const char *path, const char *label) {
|
||||
assert(label);
|
||||
|
||||
if (setfilecon(FORMAT_PROC_FD_PATH(fd), label) < 0)
|
||||
return log_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, strna(path));
|
||||
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, strna(path));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -471,6 +456,32 @@ int mac_selinux_get_our_label(char **ret_label) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int mac_selinux_get_peer_label(int socket_fd, char **ret_label) {
|
||||
assert(socket_fd >= 0);
|
||||
assert(ret_label);
|
||||
|
||||
#if HAVE_SELINUX
|
||||
int r;
|
||||
|
||||
r = selinux_init(/* force= */ false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
_cleanup_freecon_ char *con = NULL;
|
||||
if (getpeercon_raw(socket_fd, &con) < 0)
|
||||
return -errno;
|
||||
if (!con)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
*ret_label = TAKE_PTR(con);
|
||||
return 0;
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **ret_label) {
|
||||
#if HAVE_SELINUX
|
||||
_cleanup_freecon_ char *mycon = NULL, *peercon = NULL, *fcon = NULL;
|
||||
@@ -558,11 +569,11 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
return log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath);
|
||||
return log_selinux_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath);
|
||||
}
|
||||
|
||||
if (setfscreatecon_raw(filecon) < 0)
|
||||
return log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath);
|
||||
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -615,7 +626,7 @@ int mac_selinux_create_file_prepare_label(const char *path, const char *label) {
|
||||
return r;
|
||||
|
||||
if (setfscreatecon_raw(label) < 0)
|
||||
return log_enforcing_errno(errno, "Failed to set specified SELinux security context '%s' for '%s': %m", label, strna(path));
|
||||
return log_selinux_enforcing_errno(errno, "Failed to set specified SELinux security context '%s' for '%s': %m", label, strna(path));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -644,7 +655,7 @@ int mac_selinux_create_socket_prepare(const char *label) {
|
||||
return r;
|
||||
|
||||
if (setsockcreatecon(label) < 0)
|
||||
return log_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
|
||||
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -724,12 +735,12 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
if (errno == ENOENT)
|
||||
goto skipped;
|
||||
|
||||
r = log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path);
|
||||
r = log_selinux_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
if (setfscreatecon_raw(fcon) < 0) {
|
||||
r = log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
|
||||
r = log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else
|
||||
|
||||
@@ -17,6 +17,21 @@ static inline void freeconp(char **p) {
|
||||
|
||||
#define _cleanup_freecon_ _cleanup_(freeconp)
|
||||
|
||||
#define log_selinux_enforcing(...) \
|
||||
log_full(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, __VA_ARGS__)
|
||||
|
||||
#define log_selinux_enforcing_errno(error, ...) \
|
||||
({ \
|
||||
bool _enforcing = mac_selinux_enforcing(); \
|
||||
int _level = _enforcing ? LOG_ERR : LOG_WARNING; \
|
||||
int _e = (error); \
|
||||
\
|
||||
int _r = (log_get_max_level() >= LOG_PRI(_level)) \
|
||||
? log_internal(_level, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
|
||||
: -ERRNO_VALUE(_e); \
|
||||
_enforcing ? _r : 0; \
|
||||
})
|
||||
|
||||
bool mac_selinux_use(void);
|
||||
void mac_selinux_retest(void);
|
||||
bool mac_selinux_enforcing(void);
|
||||
@@ -35,6 +50,7 @@ int mac_selinux_apply_fd(int fd, const char *path, const char *label);
|
||||
|
||||
int mac_selinux_get_create_label_from_exe(const char *exe, char **ret_label);
|
||||
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 dirfd, const char *path, mode_t mode);
|
||||
|
||||
@@ -53,7 +53,7 @@ static void test_cleanup(void) {
|
||||
}
|
||||
|
||||
static void test_misc(const char* fname) {
|
||||
_cleanup_freecon_ char *label = NULL, *label2 = NULL, *label3 = NULL;
|
||||
_cleanup_freecon_ char *label = NULL, *label2 = NULL, *label3 = NULL, *label4 = NULL;
|
||||
int r;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
@@ -73,6 +73,10 @@ static void test_misc(const char* fname) {
|
||||
r = mac_selinux_get_child_mls_label(fd, fname, label2, &label3);
|
||||
log_info_errno(r, "mac_selinux_get_child_mls_label → %d, \"%s\" (%m)",
|
||||
r, strnull(label3));
|
||||
|
||||
r = mac_selinux_get_peer_label(fd, &label4);
|
||||
log_info_errno(r, "mac_selinux_get_peer_label → %d, \"%s\" (%m)",
|
||||
r, strnull(label4));
|
||||
}
|
||||
|
||||
static void test_create_file_prepare(const char* fname) {
|
||||
|
||||
Reference in New Issue
Block a user