[lxc-devel] [lxc/master] lsm: simplifcations
brauner on Github
lxc-bot at linuxcontainers.org
Mon Jan 22 11:16:56 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180122/fc9b1fa7/attachment.bin>
-------------- next part --------------
From e6e899749af3a28323fe12499dbed1faef4cacca Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 22 Jan 2018 10:48:56 +0100
Subject: [PATCH 1/5] lsm: non-functional changes
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/lsm/apparmor.c | 2 +-
src/lxc/lsm/lsm.c | 2 +-
src/lxc/lsm/lsm.h | 53 ++++++++++++++++++++++++++++++++++++--------------
src/lxc/lsm/nop.c | 2 +-
src/lxc/lsm/selinux.c | 2 +-
5 files changed, 42 insertions(+), 19 deletions(-)
diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c
index 2faa9a20d..0021001ac 100644
--- a/src/lxc/lsm/apparmor.c
+++ b/src/lxc/lsm/apparmor.c
@@ -172,7 +172,7 @@ static bool aa_needs_transition(char *curlabel)
* Notes: This relies on /proc being available.
*/
static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf,
- int use_default, int on_exec)
+ bool use_default, bool on_exec)
{
const char *label = inlabel ? inlabel : conf->lsm_aa_profile;
char *curlabel;
diff --git a/src/lxc/lsm/lsm.c b/src/lxc/lsm/lsm.c
index 79f837fc6..75f20f13b 100644
--- a/src/lxc/lsm/lsm.c
+++ b/src/lxc/lsm/lsm.c
@@ -86,7 +86,7 @@ char *lsm_process_label_get(pid_t pid)
}
int lsm_process_label_set(const char *label, struct lxc_conf *conf,
- int use_default, int on_exec)
+ bool use_default, bool on_exec)
{
if (!drv) {
ERROR("LSM driver not inited");
diff --git a/src/lxc/lsm/lsm.h b/src/lxc/lsm/lsm.h
index b915e8ddd..3b08b3be7 100644
--- a/src/lxc/lsm/lsm.h
+++ b/src/lxc/lsm/lsm.h
@@ -28,29 +28,52 @@ struct lxc_conf;
#include <sys/types.h>
+#include "../utils.h"
+
+#define LXC_LSMATTRLEN (5 + (LXC_NUMSTRLEN64) + 7 + 1)
+
struct lsm_drv {
const char *name;
- int (*enabled)(void);
+ int (*enabled)(void);
char *(*process_label_get)(pid_t pid);
- int (*process_label_set)(const char *label, struct lxc_conf *conf,
- int use_default, int on_exec);
+ int (*process_label_set)(const char *label, struct lxc_conf *conf,
+ bool use_default, bool on_exec);
};
#if HAVE_APPARMOR || HAVE_SELINUX
-void lsm_init(void);
-int lsm_enabled(void);
-const char *lsm_name(void);
-char *lsm_process_label_get(pid_t pid);
-int lsm_process_label_set(const char *label, struct lxc_conf *conf,
- int use_default, int on_exec);
+extern void lsm_init(void);
+extern int lsm_enabled(void);
+extern const char *lsm_name(void);
+extern char *lsm_process_label_get(pid_t pid);
+extern int lsm_process_label_set(const char *label, struct lxc_conf *conf,
+ bool use_default, bool on_exec);
#else
-static inline void lsm_init(void) { }
-static inline int lsm_enabled(void) { return 0; }
-static inline const char *lsm_name(void) { return "none"; }
-static inline char *lsm_process_label_get(pid_t pid) { return NULL; }
-static inline int lsm_process_label_set(const char *label,
- struct lxc_conf *conf, int use_default, int on_exec) { return 0; }
+static inline void lsm_init(void)
+{
+ return;
+}
+
+static inline int lsm_enabled(void) {
+ return 0;
+}
+
+static inline const char *lsm_name(void)
+{
+ return "none";
+}
+
+static inline char *lsm_process_label_get(pid_t pid)
+{
+ return NULL;
+}
+
+static inline int lsm_process_label_set(const char *label,
+ struct lxc_conf *conf, bool use_default,
+ bool on_exec)
+{
+ return 0;
+}
#endif
#endif
diff --git a/src/lxc/lsm/nop.c b/src/lxc/lsm/nop.c
index c13d8f528..7bb8121b8 100644
--- a/src/lxc/lsm/nop.c
+++ b/src/lxc/lsm/nop.c
@@ -30,7 +30,7 @@ static char *nop_process_label_get(pid_t pid)
}
static int nop_process_label_set(const char *label, struct lxc_conf *conf,
- int use_default, int on_exec)
+ bool use_default, bool on_exec)
{
return 0;
}
diff --git a/src/lxc/lsm/selinux.c b/src/lxc/lsm/selinux.c
index 46554d84c..857fe29a8 100644
--- a/src/lxc/lsm/selinux.c
+++ b/src/lxc/lsm/selinux.c
@@ -72,7 +72,7 @@ static char *selinux_process_label_get(pid_t pid)
* Notes: This relies on /proc being available.
*/
static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf,
- int use_default, int on_exec)
+ bool use_default, bool on_exec)
{
const char *label = inlabel ? inlabel : conf->lsm_se_context;
if (!label) {
From 47ce2cb727eb0e306ab652910cf0b3fdd5cf7e24 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 22 Jan 2018 10:54:38 +0100
Subject: [PATCH 2/5] lsm: add lsm_process_label_fd_get()
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/attach.c | 45 ++++-----------------------------------------
src/lxc/lsm/lsm.c | 36 ++++++++++++++++++++++++++++++++++++
src/lxc/lsm/lsm.h | 6 ++++++
3 files changed, 46 insertions(+), 41 deletions(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 34bdf9145..369d88183 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -88,44 +88,6 @@
lxc_log_define(lxc_attach, lxc);
-/* /proc/pid-to-str/current\0 = (5 + 21 + 7 + 1) */
-#define __LSMATTRLEN (5 + (LXC_NUMSTRLEN64) + 7 + 1)
-static int lsm_open(pid_t pid, int on_exec)
-{
- const char *name;
- char path[__LSMATTRLEN];
- int ret = -1;
- int labelfd = -1;
-
- name = lsm_name();
-
- if (strcmp(name, "nop") == 0)
- return 0;
-
- if (strcmp(name, "none") == 0)
- return 0;
-
- /* We don't support on-exec with AppArmor */
- if (strcmp(name, "AppArmor") == 0)
- on_exec = 0;
-
- if (on_exec)
- ret = snprintf(path, __LSMATTRLEN, "/proc/%d/attr/exec", pid);
- else
- ret = snprintf(path, __LSMATTRLEN, "/proc/%d/attr/current", pid);
- if (ret < 0 || ret >= __LSMATTRLEN)
- return -1;
-
- labelfd = open(path, O_RDWR);
- if (labelfd < 0) {
- SYSERROR("%s - Unable to open file descriptor to set LSM label",
- strerror(errno));
- return -1;
- }
-
- return labelfd;
-}
-
static int lsm_set_label_at(int lsm_labelfd, int on_exec, char *lsm_label)
{
int fret = -1;
@@ -1396,11 +1358,12 @@ int lxc_attach(const char *name, const char *lxcpath,
if ((options->namespaces & CLONE_NEWNS) &&
(options->attach_flags & LXC_ATTACH_LSM) &&
init_ctx->lsm_label) {
- int labelfd, on_exec;
int ret = -1;
+ int labelfd;
+ bool on_exec;
- on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? 1 : 0;
- labelfd = lsm_open(attached_pid, on_exec);
+ on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? true : false;
+ labelfd = lsm_process_label_fd_get(attached_pid, on_exec);
if (labelfd < 0)
goto close_mainloop;
TRACE("Opened LSM label file descriptor %d", labelfd);
diff --git a/src/lxc/lsm/lsm.c b/src/lxc/lsm/lsm.c
index 75f20f13b..98bf083bb 100644
--- a/src/lxc/lsm/lsm.c
+++ b/src/lxc/lsm/lsm.c
@@ -85,6 +85,42 @@ char *lsm_process_label_get(pid_t pid)
return drv->process_label_get(pid);
}
+int lsm_process_label_fd_get(pid_t pid, bool on_exec)
+{
+ int ret = -1;
+ int labelfd = -1;
+ const char *name;
+ char path[LXC_LSMATTRLEN];
+
+ name = lsm_name();
+
+ if (strcmp(name, "nop") == 0)
+ return 0;
+
+ if (strcmp(name, "none") == 0)
+ return 0;
+
+ /* We don't support on-exec with AppArmor */
+ if (strcmp(name, "AppArmor") == 0)
+ on_exec = 0;
+
+ if (on_exec)
+ ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/exec", pid);
+ else
+ ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/current", pid);
+ if (ret < 0 || ret >= LXC_LSMATTRLEN)
+ return -1;
+
+ labelfd = open(path, O_RDWR);
+ if (labelfd < 0) {
+ SYSERROR("%s - Unable to %s LSM label file descriptor",
+ name, strerror(errno));
+ return -1;
+ }
+
+ return labelfd;
+}
+
int lsm_process_label_set(const char *label, struct lxc_conf *conf,
bool use_default, bool on_exec)
{
diff --git a/src/lxc/lsm/lsm.h b/src/lxc/lsm/lsm.h
index 3b08b3be7..db8738411 100644
--- a/src/lxc/lsm/lsm.h
+++ b/src/lxc/lsm/lsm.h
@@ -48,6 +48,7 @@ extern const char *lsm_name(void);
extern char *lsm_process_label_get(pid_t pid);
extern int lsm_process_label_set(const char *label, struct lxc_conf *conf,
bool use_default, bool on_exec);
+extern int lsm_process_label_fd_get(pid_t pid, bool on_exec);
#else
static inline void lsm_init(void)
{
@@ -74,6 +75,11 @@ static inline int lsm_process_label_set(const char *label,
{
return 0;
}
+
+static inline int lsm_process_label_fd_get(pid_t pid, bool on_exec)
+{
+ return 0;
+}
#endif
#endif
From d3ba7c987201cb461ed92c027e9f424737fbe341 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 22 Jan 2018 11:54:21 +0100
Subject: [PATCH 3/5] lsm: add lsm_process_label_set_at()
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/attach.c | 68 ++++---------------------------------------------------
src/lxc/lsm/lsm.c | 53 +++++++++++++++++++++++++++++++++++++++++++
src/lxc/lsm/lsm.h | 8 +++++++
3 files changed, 65 insertions(+), 64 deletions(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 369d88183..45979bcdc 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -88,66 +88,6 @@
lxc_log_define(lxc_attach, lxc);
-static int lsm_set_label_at(int lsm_labelfd, int on_exec, char *lsm_label)
-{
- int fret = -1;
- const char *name;
- char *command = NULL;
-
- name = lsm_name();
-
- if (strcmp(name, "nop") == 0)
- return 0;
-
- if (strcmp(name, "none") == 0)
- return 0;
-
- /* We don't support on-exec with AppArmor */
- if (strcmp(name, "AppArmor") == 0)
- on_exec = 0;
-
- if (strcmp(name, "AppArmor") == 0) {
- int size;
-
- command =
- malloc(strlen(lsm_label) + strlen("changeprofile ") + 1);
- if (!command) {
- SYSERROR("Failed to write apparmor profile.");
- goto out;
- }
-
- size = sprintf(command, "changeprofile %s", lsm_label);
- if (size < 0) {
- SYSERROR("Failed to write apparmor profile.");
- goto out;
- }
-
- if (write(lsm_labelfd, command, size + 1) < 0) {
- SYSERROR("Unable to set LSM label: %s.", command);
- goto out;
- }
- INFO("Set LSM label to: %s.", command);
- } else if (strcmp(name, "SELinux") == 0) {
- if (write(lsm_labelfd, lsm_label, strlen(lsm_label) + 1) < 0) {
- SYSERROR("Unable to set LSM label: %s.", lsm_label);
- goto out;
- }
- INFO("Set LSM label to: %s.", lsm_label);
- } else {
- ERROR("Unable to restore label for unknown LSM: %s.", name);
- goto out;
- }
- fret = 0;
-
-out:
- free(command);
-
- if (lsm_labelfd != -1)
- close(lsm_labelfd);
-
- return fret;
-}
-
/* /proc/pid-to-str/status\0 = (5 + 21 + 7 + 1) */
#define __PROC_STATUS_LEN (5 + (LXC_NUMSTRLEN64) + 7 + 1)
static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
@@ -922,15 +862,15 @@ static int attach_child_main(struct attach_clone_payload *payload)
}
if (needs_lsm) {
- int on_exec;
+ bool on_exec;
/* Change into our new LSM profile. */
- on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? 1 : 0;
- ret = lsm_set_label_at(lsm_fd, on_exec, init_ctx->lsm_label);
+ on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? true : false;
+ ret = lsm_process_label_set_at(lsm_fd, init_ctx->lsm_label, on_exec);
close(lsm_fd);
if (ret < 0)
goto on_error;
- TRACE("Set LSM label");
+ TRACE("Set %s LSM label to \"%s\"", lsm_name(), init_ctx->lsm_label);
}
if (init_ctx->container && init_ctx->container->lxc_conf &&
diff --git a/src/lxc/lsm/lsm.c b/src/lxc/lsm/lsm.c
index 98bf083bb..677f53a61 100644
--- a/src/lxc/lsm/lsm.c
+++ b/src/lxc/lsm/lsm.c
@@ -121,6 +121,59 @@ int lsm_process_label_fd_get(pid_t pid, bool on_exec)
return labelfd;
}
+int lsm_process_label_set_at(int label_fd, const char *label, bool on_exec)
+{
+ int ret = -1;
+ const char *name;
+
+ name = lsm_name();
+
+ if (strcmp(name, "nop") == 0)
+ return 0;
+
+ if (strcmp(name, "none") == 0)
+ return 0;
+
+ /* We don't support on-exec with AppArmor */
+ if (strcmp(name, "AppArmor") == 0)
+ on_exec = false;
+
+ if (strcmp(name, "AppArmor") == 0) {
+ size_t len;
+ char *command;
+
+ if (on_exec) {
+ ERROR("Changing AppArmor profile on exec not supported");
+ return -EINVAL;
+ }
+
+ len = strlen(label) + strlen("changeprofile ") + 1;
+ command = malloc(len);
+ if (!command)
+ return -1;
+
+ ret = snprintf(command, len, "changeprofile %s", label);
+ if (ret < 0 || (size_t)ret >= len) {
+ free(command);
+ return -1;
+ }
+
+ ret = lxc_write_nointr(label_fd, command, len - 1);
+ free(command);
+ } else if (strcmp(name, "SELinux") == 0) {
+ ret = lxc_write_nointr(label_fd, label, strlen(label));
+ } else {
+ ret = -EINVAL;
+ }
+ if (ret < 0) {
+ SYSERROR("Failed to set %s label \"%s\"", name, label);
+ return -1;
+ }
+
+ INFO("Set %s label to \"%s\"", name, label);
+ return 0;
+}
+
int lsm_process_label_set(const char *label, struct lxc_conf *conf,
bool use_default, bool on_exec)
{
diff --git a/src/lxc/lsm/lsm.h b/src/lxc/lsm/lsm.h
index db8738411..33a412b7b 100644
--- a/src/lxc/lsm/lsm.h
+++ b/src/lxc/lsm/lsm.h
@@ -49,6 +49,8 @@ extern char *lsm_process_label_get(pid_t pid);
extern int lsm_process_label_set(const char *label, struct lxc_conf *conf,
bool use_default, bool on_exec);
extern int lsm_process_label_fd_get(pid_t pid, bool on_exec);
+extern int lsm_process_label_set_at(int label_fd, const char *label,
+ bool on_exec);
#else
static inline void lsm_init(void)
{
@@ -80,6 +82,12 @@ static inline int lsm_process_label_fd_get(pid_t pid, bool on_exec)
{
return 0;
}
+
+extern int lsm_process_label_set_at(int label_fd, const char *label,
+ bool on_exec)
+{
+ return 0;
+}
#endif
#endif
From 5288a74faaa59680cab48f339e97c4ed6ce2a139 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 22 Jan 2018 12:02:44 +0100
Subject: [PATCH 4/5] apparmor: do not call aa_change_profile()
We can simply write the label ourselves. There's no magic happening.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/lsm/apparmor.c | 20 +++++++++++++++-----
src/lxc/utils.h | 9 +++++++++
2 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c
index 0021001ac..85b70de8d 100644
--- a/src/lxc/lsm/apparmor.c
+++ b/src/lxc/lsm/apparmor.c
@@ -25,11 +25,10 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
-#include <sys/apparmor.h>
#include <sys/vfs.h>
#include "log.h"
-#include "lsm/lsm.h"
+#include "lsm.h"
#include "conf.h"
#include "utils.h"
@@ -174,6 +173,8 @@ static bool aa_needs_transition(char *curlabel)
static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf,
bool use_default, bool on_exec)
{
+ int label_fd, ret;
+ pid_t tid;
const char *label = inlabel ? inlabel : conf->lsm_aa_profile;
char *curlabel;
@@ -230,12 +231,21 @@ static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf
return 0;
}
- if (aa_change_profile(label) < 0) {
- SYSERROR("failed to change apparmor profile to %s", label);
+ tid = lxc_raw_gettid();
+ label_fd = lsm_process_label_fd_get(tid, on_exec);
+ if (label_fd < 0) {
+ SYSERROR("Failed to change apparmor profile to %s", label);
return -1;
}
- INFO("changed apparmor profile to %s", label);
+ ret = lsm_process_label_set_at(label_fd, label, on_exec);
+ close(label_fd);
+ if (ret < 0) {
+ SYSERROR("Failed to change apparmor profile to %s", label);
+ return -1;
+ }
+
+ INFO("Changed apparmor profile to %s", label);
return 0;
}
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index f8cf26fbf..188b646a3 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -541,4 +541,13 @@ static inline uint64_t lxc_getpagesize(void)
*/
extern uint64_t lxc_find_next_power2(uint64_t n);
+static inline pid_t lxc_raw_gettid(void)
+{
+#ifdef SYS_gettid
+ return syscall(SYS_gettid);
+#else
+ return lxc_raw_getpid();
+#endif
+}
+
#endif /* __LXC_UTILS_H */
From 05f0f93a93452070006524ac22a6f51e19f8271f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 22 Jan 2018 12:14:21 +0100
Subject: [PATCH 5/5] autotools: do not link against libapparmor
Since we write the label directly without going through the AppArmor API it
doesn't make sense to link against it.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
configure.ac | 5 -----
src/lxc/Makefile.am | 4 ++--
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/configure.ac b/configure.ac
index 0bcd75a28..6713539b4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -258,11 +258,6 @@ if test "$enable_apparmor" = "auto" ; then
fi
AM_CONDITIONAL([ENABLE_APPARMOR], [test "x$enable_apparmor" = "xyes"])
-AM_COND_IF([ENABLE_APPARMOR],
- [AC_CHECK_HEADER([sys/apparmor.h],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])])
- AC_CHECK_LIB([apparmor], [aa_change_profile],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])])
- AC_SUBST([APPARMOR_LIBS], [-lapparmor])])
-
# GnuTLS
AC_ARG_ENABLE([gnutls],
[AC_HELP_STRING([--enable-gnutls], [enable GnuTLS support [default=auto]])],
diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index 895684e0b..8f9a7ab29 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -207,7 +207,7 @@ liblxc_la_LDFLAGS = \
-Wl,-soname,liblxc.so.$(firstword $(subst ., , at LXC_ABI@)) \
-version-info @LXC_ABI_MAJOR@
-liblxc_la_LIBADD = $(CAP_LIBS) $(APPARMOR_LIBS) $(SELINUX_LIBS) $(SECCOMP_LIBS)
+liblxc_la_LIBADD = $(CAP_LIBS) $(SELINUX_LIBS) $(SECCOMP_LIBS)
if ENABLE_CGMANAGER
liblxc_la_LIBADD += $(CGMANAGER_LIBS) $(DBUS_LIBS) $(NIH_LIBS) $(NIH_DBUS_LIBS)
@@ -264,7 +264,7 @@ AM_LDFLAGS = -Wl,-E
if ENABLE_RPATH
AM_LDFLAGS += -Wl,-rpath -Wl,$(libdir)
endif
-LDADD=liblxc.la @CAP_LIBS@ @APPARMOR_LIBS@ @SELINUX_LIBS@ @SECCOMP_LIBS@
+LDADD=liblxc.la @CAP_LIBS@ @SELINUX_LIBS@ @SECCOMP_LIBS@
lxc_attach_SOURCES = tools/lxc_attach.c tools/arguments.c
lxc_autostart_SOURCES = tools/lxc_autostart.c tools/arguments.c
More information about the lxc-devel
mailing list