diff options
-rw-r--r-- | src/basic/smack-util.c | 117 | ||||
-rw-r--r-- | src/basic/smack-util.h | 24 | ||||
-rw-r--r-- | src/basic/util.c | 70 | ||||
-rw-r--r-- | src/basic/util.h | 3 | ||||
-rw-r--r-- | src/core/execute.c | 10 | ||||
-rw-r--r-- | src/core/socket.c | 6 | ||||
-rw-r--r-- | src/udev/udev-node.c | 4 |
7 files changed, 170 insertions, 64 deletions
diff --git a/src/basic/smack-util.c b/src/basic/smack-util.c index 047aa294f4..6d5c205117 100644 --- a/src/basic/smack-util.c +++ b/src/basic/smack-util.c @@ -32,109 +32,93 @@ #define SMACK_FLOOR_LABEL "_" #define SMACK_STAR_LABEL "*" -bool mac_smack_use(void) { #ifdef HAVE_SMACK +bool mac_smack_use(void) { static int cached_use = -1; if (cached_use < 0) cached_use = access("/sys/fs/smackfs/", F_OK) >= 0; return cached_use; -#else - return false; -#endif } -int mac_smack_apply(const char *path, const char *label) { - int r = 0; +static const char* const smack_attr_table[_SMACK_ATTR_MAX] = { + [SMACK_ATTR_ACCESS] = "security.SMACK64", + [SMACK_ATTR_EXEC] = "security.SMACK64EXEC", + [SMACK_ATTR_MMAP] = "security.SMACK64MMAP", + [SMACK_ATTR_TRANSMUTE] = "security.SMACK64TRANSMUTE", + [SMACK_ATTR_IPIN] = "security.SMACK64IPIN", + [SMACK_ATTR_IPOUT] = "security.SMACK64IPOUT", +}; + +DEFINE_STRING_TABLE_LOOKUP(smack_attr, SmackAttr); +int mac_smack_read(const char *path, SmackAttr attr, char **label) { assert(path); + assert(attr >= 0 && attr < _SMACK_ATTR_MAX); + assert(label); -#ifdef HAVE_SMACK if (!mac_smack_use()) return 0; - if (label) - r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0); - else - r = lremovexattr(path, "security.SMACK64"); - if (r < 0) - return -errno; -#endif - - return r; + return getxattr_malloc(path, smack_attr_to_string(attr), label, true); } -int mac_smack_apply_fd(int fd, const char *label) { - int r = 0; - +int mac_smack_read_fd(int fd, SmackAttr attr, char **label) { assert(fd >= 0); + assert(attr >= 0 && attr < _SMACK_ATTR_MAX); + assert(label); -#ifdef HAVE_SMACK if (!mac_smack_use()) return 0; - if (label) - r = fsetxattr(fd, "security.SMACK64", label, strlen(label), 0); - else - r = fremovexattr(fd, "security.SMACK64"); - if (r < 0) - return -errno; -#endif - - return r; + return fgetxattr_malloc(fd, smack_attr_to_string(attr), label); } -int mac_smack_apply_ip_out_fd(int fd, const char *label) { - int r = 0; +int mac_smack_apply(const char *path, SmackAttr attr, const char *label) { + int r; - assert(fd >= 0); + assert(path); + assert(attr >= 0 && attr < _SMACK_ATTR_MAX); -#ifdef HAVE_SMACK if (!mac_smack_use()) return 0; if (label) - r = fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0); + r = lsetxattr(path, smack_attr_to_string(attr), label, strlen(label), 0); else - r = fremovexattr(fd, "security.SMACK64IPOUT"); + r = lremovexattr(path, smack_attr_to_string(attr)); if (r < 0) return -errno; -#endif - return r; + return 0; } -int mac_smack_apply_ip_in_fd(int fd, const char *label) { - int r = 0; +int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) { + int r; assert(fd >= 0); + assert(attr >= 0 && attr < _SMACK_ATTR_MAX); -#ifdef HAVE_SMACK if (!mac_smack_use()) return 0; if (label) - r = fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0); + r = fsetxattr(fd, smack_attr_to_string(attr), label, strlen(label), 0); else - r = fremovexattr(fd, "security.SMACK64IPIN"); + r = fremovexattr(fd, smack_attr_to_string(attr)); if (r < 0) return -errno; -#endif - return r; + return 0; } int mac_smack_apply_pid(pid_t pid, const char *label) { - -#ifdef HAVE_SMACK const char *p; -#endif int r = 0; assert(label); -#ifdef HAVE_SMACK if (!mac_smack_use()) return 0; @@ -142,21 +126,16 @@ int mac_smack_apply_pid(pid_t pid, const char *label) { r = write_string_file(p, label, 0); if (r < 0) return r; -#endif return r; } int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { - -#ifdef HAVE_SMACK struct stat st; -#endif int r = 0; assert(path); -#ifdef HAVE_SMACK if (!mac_smack_use()) return 0; @@ -202,7 +181,37 @@ int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path); } -#endif return r; } + + +#else +bool mac_smack_use(void) { + return false; +} + +int mac_smack_read(const char *path, SmackAttr attr, char **label) { + return -EOPNOTSUPP; +} + +int mac_smack_read_fd(int fd, SmackAttr attr, char **label) { + return -EOPNOTSUPP; +} + +int mac_smack_apply(const char *path, SmackAttr attr, const char *label) { + return 0; +} + +int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) { + return 0; +} + +int mac_smack_apply_pid(pid_t pid, const char *label) { + return 0; +} + +int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { + return 0; +} +#endif diff --git a/src/basic/smack-util.h b/src/basic/smack-util.h index 50f55b1f4b..1052cecf4c 100644 --- a/src/basic/smack-util.h +++ b/src/basic/smack-util.h @@ -25,12 +25,28 @@ #include <stdbool.h> +#include "macro.h" + +typedef enum SmackAttr { + SMACK_ATTR_ACCESS = 0, + SMACK_ATTR_EXEC = 1, + SMACK_ATTR_MMAP = 2, + SMACK_ATTR_TRANSMUTE = 3, + SMACK_ATTR_IPIN = 4, + SMACK_ATTR_IPOUT = 5, + _SMACK_ATTR_MAX, + _SMACK_ATTR_INVALID = -1, +} SmackAttr; + bool mac_smack_use(void); 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); +const char* smack_attr_to_string(SmackAttr i) _const_; +SmackAttr smack_attr_from_string(const char *s) _pure_; +int mac_smack_read(const char *path, SmackAttr attr, char **label); +int mac_smack_read_fd(int fd, SmackAttr attr, char **label); +int mac_smack_apply(const char *path, SmackAttr attr, const char *label); +int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label); + int mac_smack_apply_pid(pid_t pid, const char *label); -int mac_smack_apply_ip_in_fd(int fd, const char *label); -int mac_smack_apply_ip_out_fd(int fd, const char *label); diff --git a/src/basic/util.c b/src/basic/util.c index a968e2156d..af58dc3766 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -6603,3 +6603,73 @@ int reset_uid_gid(void) { return 0; } + +int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) { + char *v; + size_t l; + ssize_t n; + + assert(path); + assert(name); + assert(value); + + for (l = 100; ; l = (size_t) n + 1) { + v = new0(char, l); + if (!v) + return -ENOMEM; + + if (allow_symlink) + n = lgetxattr(path, name, v, l); + else + n = getxattr(path, name, v, l); + + if (n >= 0 && (size_t) n < l) { + *value = v; + return n; + } + + free(v); + + if (n < 0 && errno != ERANGE) + return -errno; + + if (allow_symlink) + n = lgetxattr(path, name, NULL, 0); + else + n = getxattr(path, name, NULL, 0); + if (n < 0) + return -errno; + } +} + +int fgetxattr_malloc(int fd, const char *name, char **value) { + char *v; + size_t l; + ssize_t n; + + assert(fd >= 0); + assert(name); + assert(value); + + for (l = 100; ; l = (size_t) n + 1) { + v = new0(char, l); + if (!v) + return -ENOMEM; + + n = fgetxattr(fd, name, v, l); + + if (n >= 0 && (size_t) n < l) { + *value = v; + return n; + } + + free(v); + + if (n < 0 && errno != ERANGE) + return -errno; + + n = fgetxattr(fd, name, NULL, 0); + if (n < 0) + return -errno; + } +} diff --git a/src/basic/util.h b/src/basic/util.h index 88c44273d4..0a0fba9012 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -919,3 +919,6 @@ int parse_mode(const char *s, mode_t *ret); int mount_move_root(const char *path); int reset_uid_gid(void); + +int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink); +int fgetxattr_malloc(int fd, const char *name, char **value); diff --git a/src/core/execute.c b/src/core/execute.c index 21721dc240..f14ae4d8a6 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1719,7 +1719,15 @@ static int exec_child( } #ifdef SMACK_DEFAULT_PROCESS_LABEL else { - r = mac_smack_apply_pid(0, SMACK_DEFAULT_PROCESS_LABEL); + _cleanup_free_ char *exec_label = NULL; + + r = mac_smack_read(command->path, SMACK_ATTR_EXEC, &exec_label); + if (r < 0 && r != -ENODATA && r != -EOPNOTSUPP) { + *exit_status = EXIT_SMACK_PROCESS_LABEL; + return r; + } + + r = mac_smack_apply_pid(0, exec_label ? : SMACK_DEFAULT_PROCESS_LABEL); if (r < 0) { *exit_status = EXIT_SMACK_PROCESS_LABEL; return r; diff --git a/src/core/socket.c b/src/core/socket.c index 87631f8753..a387057473 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -923,13 +923,13 @@ static void socket_apply_socket_options(Socket *s, int fd) { log_unit_warning_errno(UNIT(s), errno, "TCP_CONGESTION failed: %m"); if (s->smack_ip_in) { - r = mac_smack_apply_ip_in_fd(fd, s->smack_ip_in); + r = mac_smack_apply_fd(fd, SMACK_ATTR_IPIN, s->smack_ip_in); if (r < 0) log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_in_fd: %m"); } if (s->smack_ip_out) { - r = mac_smack_apply_ip_out_fd(fd, s->smack_ip_out); + r = mac_smack_apply_fd(fd, SMACK_ATTR_IPOUT, s->smack_ip_out); if (r < 0) log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_out_fd: %m"); } @@ -946,7 +946,7 @@ static void socket_apply_fifo_options(Socket *s, int fd) { log_unit_warning_errno(UNIT(s), errno, "F_SETPIPE_SZ: %m"); if (s->smack) { - r = mac_smack_apply_fd(fd, s->smack); + r = mac_smack_apply_fd(fd, SMACK_ATTR_ACCESS, s->smack); if (r < 0) log_unit_error_errno(UNIT(s), r, "mac_smack_apply_fd: %m"); } diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index d824172b89..e730fb45f1 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -309,7 +309,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, } else if (streq(name, "smack")) { smack = true; - r = mac_smack_apply(devnode, label); + r = mac_smack_apply(devnode, SMACK_ATTR_ACCESS, label); if (r < 0) log_error_errno(r, "SECLABEL: failed to set SMACK label '%s': %m", label); else @@ -323,7 +323,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, if (!selinux) mac_selinux_fix(devnode, true, false); if (!smack) - mac_smack_apply(devnode, NULL); + mac_smack_apply(devnode, SMACK_ATTR_ACCESS, NULL); } /* always update timestamp when we re-use the node, like on media change events */ |