smack: rework SMACK label fixing code to follow more closely the semantics of the matching selinux code

This commit is contained in:
Lennart Poettering 2014-10-23 18:34:58 +02:00
parent d1ce2089b4
commit 5dfc54615a
5 changed files with 55 additions and 47 deletions

View file

@ -23,19 +23,15 @@
#include "util.h"
int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
int r = 0;
int r, q;
if (mac_selinux_use()) {
r = mac_selinux_fix(path, ignore_enoent, ignore_erofs);
if (r < 0)
return r;
}
r = mac_selinux_fix(path, ignore_enoent, ignore_erofs);
q = mac_smack_fix(path, ignore_enoent, ignore_erofs);
if (mac_smack_use()) {
r = mac_smack_fix(path);
if (r < 0)
return r;
}
if (r < 0)
return r;
if (q < 0)
return q;
return r;
return 0;
}

View file

@ -46,7 +46,7 @@ static int label_mkdir(const char *path, mode_t mode) {
if (r < 0 && errno != EEXIST)
return -errno;
r = mac_smack_fix(path);
r = mac_smack_fix(path, false, false);
if (r < 0)
return r;
}

View file

@ -113,22 +113,25 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
#ifdef HAVE_SELINUX
struct stat st;
security_context_t fcon;
assert(path);
/* if mac_selinux_init() wasn't called before we are a NOOP */
if (!label_hnd)
return 0;
r = lstat(path, &st);
if (r == 0) {
if (r >= 0) {
_cleanup_security_context_free_ security_context_t fcon = NULL;
r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);
/* If there's no label to set, then exit without warning */
if (r < 0 && errno == ENOENT)
return 0;
if (r == 0) {
if (r >= 0) {
r = lsetfilecon(path, fcon);
freecon(fcon);
/* If the FS doesn't support labels, then exit without warning */
if (r < 0 && errno == ENOTSUP)
@ -144,8 +147,7 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
if (ignore_erofs && errno == EROFS)
return 0;
log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
"Unable to fix label of %s: %m", path);
log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, "Unable to fix SELinux label of %s: %m", path);
r = security_getenforce() == 1 ? -errno : 0;
}
#endif
@ -156,11 +158,10 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
void mac_selinux_finish(void) {
#ifdef HAVE_SELINUX
if (!mac_selinux_use())
if (!label_hnd)
return;
if (label_hnd)
selabel_close(label_hnd);
selabel_close(label_hnd);
#endif
}

View file

@ -120,17 +120,14 @@ int mac_smack_apply_ip_in_fd(int fd, const char *label) {
return r;
}
int mac_smack_fix(const char *path) {
int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
int r = 0;
#ifdef HAVE_SMACK
struct stat sb;
const char *label;
#endif
struct stat st;
assert(path);
#ifdef HAVE_SMACK
if (!mac_smack_use())
return 0;
@ -140,28 +137,42 @@ int mac_smack_fix(const char *path) {
if (!path_startswith(path, "/dev"))
return 0;
r = lstat(path, &sb);
if (r < 0)
return -errno;
r = lstat(path, &st);
if (r >= 0) {
const char *label;
/*
* Label directories and character devices "*".
* Label symlinks "_".
* Don't change anything else.
*/
if (S_ISDIR(sb.st_mode))
label = SMACK_STAR_LABEL;
else if (S_ISLNK(sb.st_mode))
label = SMACK_FLOOR_LABEL;
else if (S_ISCHR(sb.st_mode))
label = SMACK_STAR_LABEL;
else
return 0;
/*
* Label directories and character devices "*".
* Label symlinks "_".
* Don't change anything else.
*/
if (S_ISDIR(st.st_mode))
label = SMACK_STAR_LABEL;
else if (S_ISLNK(st.st_mode))
label = SMACK_FLOOR_LABEL;
else if (S_ISCHR(st.st_mode))
label = SMACK_STAR_LABEL;
else
return 0;
r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
/* If the FS doesn't support labels, then exit without warning */
if (r < 0 && errno == ENOTSUP)
return 0;
}
r = setxattr(path, "security.SMACK64", label, strlen(label), 0);
if (r < 0) {
log_error("Smack relabeling \"%s\" %m", path);
return -errno;
/* Ignore ENOENT in some cases */
if (ignore_enoent && errno == ENOENT)
return 0;
if (ignore_erofs && errno == EROFS)
return 0;
log_debug("Unable to fix SMACK label of %s: %m", path);
r = -errno;
}
#endif

View file

@ -30,7 +30,7 @@
bool mac_smack_use(void);
int mac_smack_fix(const char *path);
int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
int mac_smack_apply(const char *path, const char *label);
int mac_smack_apply_fd(int fd, const char *label);