mirror of
https://github.com/systemd/systemd.git
synced 2026-07-12 18:44:14 +00:00
smack: rework security labeling for multiple frameworks
This commit is contained in:
committed by
Lennart Poettering
parent
e49d3c0167
commit
b9c1bc28eb
@@ -27,41 +27,41 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_XATTR
|
||||
#include <sys/xattr.h>
|
||||
#endif
|
||||
#ifdef HAVE_SELINUX
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/label.h>
|
||||
#endif
|
||||
|
||||
#include "label.h"
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
#include "path-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "smack-util.h"
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
#include "selinux-util.h"
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/label.h>
|
||||
|
||||
static struct selabel_handle *label_hnd = NULL;
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_SMACK
|
||||
#include <sys/xattr.h>
|
||||
#include <string.h>
|
||||
#define FLOOR_LABEL "_"
|
||||
#define STAR_LABEL "*"
|
||||
|
||||
static void smack_relabel_in_dev(const char *path) {
|
||||
static int smack_relabel_in_dev(const char *path) {
|
||||
int r = 0;
|
||||
|
||||
#ifdef HAVE_SMACK
|
||||
struct stat sb;
|
||||
const char *label;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* Path must be in /dev and must exist
|
||||
*/
|
||||
if (!path_equal(path, "/dev") &&
|
||||
!path_startswith(path, "/dev"))
|
||||
return;
|
||||
if (!path_startswith(path, "/dev"))
|
||||
return 0;
|
||||
|
||||
r = lstat(path, &sb);
|
||||
if (r < 0)
|
||||
return;
|
||||
return -errno;
|
||||
|
||||
/*
|
||||
* Label directories and character devices "*".
|
||||
@@ -69,21 +69,24 @@ static void smack_relabel_in_dev(const char *path) {
|
||||
* Don't change anything else.
|
||||
*/
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
label = STAR_LABEL;
|
||||
label = SMACK_STAR_LABEL;
|
||||
else if (S_ISLNK(sb.st_mode))
|
||||
label = FLOOR_LABEL;
|
||||
label = SMACK_FLOOR_LABEL;
|
||||
else if (S_ISCHR(sb.st_mode))
|
||||
label = STAR_LABEL;
|
||||
label = SMACK_STAR_LABEL;
|
||||
else
|
||||
return;
|
||||
return 0;
|
||||
|
||||
r = setxattr(path, "security.SMACK64", label, strlen(label), 0);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
log_error("Smack relabeling \"%s\" %s", path, strerror(errno));
|
||||
return;
|
||||
}
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int label_init(const char *prefix) {
|
||||
int r = 0;
|
||||
|
||||
@@ -131,14 +134,14 @@ int label_init(const char *prefix) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
|
||||
static int label_fix_selinux(const char *path, bool ignore_enoent, bool ignore_erofs) {
|
||||
int r = 0;
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
struct stat st;
|
||||
security_context_t fcon;
|
||||
|
||||
if (!use_selinux() || !label_hnd)
|
||||
if (!label_hnd)
|
||||
return 0;
|
||||
|
||||
r = lstat(path, &st);
|
||||
@@ -172,9 +175,24 @@ int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
|
||||
r = security_getenforce() == 1 ? -errno : 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SMACK
|
||||
smack_relabel_in_dev(path);
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
|
||||
int r = 0;
|
||||
|
||||
if (use_selinux()) {
|
||||
r = label_fix_selinux(path, ignore_enoent, ignore_erofs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (use_smack()) {
|
||||
r = smack_relabel_in_dev(path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -252,9 +270,6 @@ int label_context_set(const char *path, mode_t mode) {
|
||||
if (r < 0 && security_getenforce() == 0)
|
||||
r = 0;
|
||||
#endif
|
||||
#ifdef HAVE_SMACK
|
||||
smack_relabel_in_dev(path);
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -307,15 +322,15 @@ void label_free(const char *label) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int label_mkdir(const char *path, mode_t mode) {
|
||||
int r;
|
||||
static int label_mkdir_selinux(const char *path, mode_t mode) {
|
||||
int r = 0;
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
/* Creates a directory and labels it according to the SELinux policy */
|
||||
security_context_t fcon = NULL;
|
||||
|
||||
if (!use_selinux() || !label_hnd)
|
||||
goto skipped;
|
||||
if (!label_hnd)
|
||||
return 0;
|
||||
|
||||
if (path_is_absolute(path))
|
||||
r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFDIR);
|
||||
@@ -348,17 +363,34 @@ int label_mkdir(const char *path, mode_t mode) {
|
||||
finish:
|
||||
setfscreatecon(NULL);
|
||||
freecon(fcon);
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int label_mkdir(const char *path, mode_t mode) {
|
||||
int r;
|
||||
|
||||
if (use_selinux()) {
|
||||
r = label_mkdir_selinux(path, mode);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (use_smack()) {
|
||||
r = mkdir(path, mode);
|
||||
if (r < 0 && errno != EEXIST)
|
||||
return -errno;
|
||||
|
||||
r = smack_relabel_in_dev(path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
skipped:
|
||||
#endif
|
||||
r = mkdir(path, mode);
|
||||
if (r)
|
||||
if (r < 0 && errno != EEXIST)
|
||||
return -errno;
|
||||
#ifdef HAVE_SMACK
|
||||
smack_relabel_in_dev(path);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SMACK_FLOOR_LABEL "_"
|
||||
#define SMACK_STAR_LABEL "*"
|
||||
|
||||
bool use_smack(void);
|
||||
|
||||
int smack_label_path(const char *path, const char *label);
|
||||
int smack_label_fd(int fd, const char *label);
|
||||
int smack_label_ip_in_fd(int fd, const char *label);
|
||||
|
||||
Reference in New Issue
Block a user