From 7b9c9ab810eb8746cece22de1dfec375caf4cd13 Mon Sep 17 00:00:00 2001 From: WaLyong Cho Date: Tue, 28 Jul 2015 02:40:50 +0900 Subject: util: add getxattr helper apis To get xattr of given path or fd on newly allocated buffer, add new helper api getxattr_malloc() and fgetxattr_malloc(). --- src/basic/util.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/basic/util.h | 3 +++ 2 files changed, 73 insertions(+) (limited to 'src') 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); -- cgit v1.2.3-54-g00ecf From 5ab58c2091636209231fc3fd5bf97f21b77deb88 Mon Sep 17 00:00:00 2001 From: WaLyong Cho Date: Tue, 28 Jul 2015 02:43:55 +0900 Subject: smack-util: revise smack-util apis and add read smack attr apis - Add smack xattr lookup table - Unify all of mac_smack_apply_xxx{_fd}() to mac_smack_apply() and mac_smack_apply_fd(). - Add smack xattr read apis similar with apply apis as mac_smack_read{_fd}(). --- src/basic/smack-util.c | 117 ++++++++++++++++++++++++++----------------------- src/basic/smack-util.h | 24 ++++++++-- src/core/socket.c | 6 +-- src/udev/udev-node.c | 4 +- 4 files changed, 88 insertions(+), 63 deletions(-) (limited to 'src') 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 +#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/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 */ -- cgit v1.2.3-54-g00ecf From e419a0e31089994ecd1d9019c791e63d13b37584 Mon Sep 17 00:00:00 2001 From: WaLyong Cho Date: Tue, 28 Jul 2015 02:55:35 +0900 Subject: core: set default process label only exec label is none When command path has access label and no SmackProcessLabel= is not set, default process label will be set. But if the default process label has no rule for the access label of the command path then smack access error will be occurred. So, if the command path has execute label then the child have to set its label to the same of execute label of command path instead of default process label. --- src/core/execute.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') 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; -- cgit v1.2.3-54-g00ecf