Skip to content

Commit

Permalink
Merge pull request #2102 from brauner/2018-01-22/lsm_simplifications
Browse files Browse the repository at this point in the history
lsm: simplifcations
  • Loading branch information
hallyn committed Jan 29, 2018
2 parents cf73b78 + 05f0f93 commit 26f0e91
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 136 deletions.
5 changes: 0 additions & 5 deletions configure.ac
Expand Up @@ -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]])],
Expand Down
4 changes: 2 additions & 2 deletions src/lxc/Makefile.am
Expand Up @@ -207,7 +207,7 @@ liblxc_la_LDFLAGS = \
-Wl,-soname,liblxc.so.$(firstword $(subst ., ,@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)
Expand Down Expand Up @@ -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
Expand Down
113 changes: 8 additions & 105 deletions src/lxc/attach.c
Expand Up @@ -88,104 +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;
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)
Expand Down Expand Up @@ -962,15 +864,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 &&
Expand Down Expand Up @@ -1409,11 +1311,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);
Expand Down
22 changes: 16 additions & 6 deletions src/lxc/lsm/apparmor.c
Expand Up @@ -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"

Expand Down Expand Up @@ -172,8 +171,10 @@ 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)
{
int label_fd, ret;
pid_t tid;
const char *label = inlabel ? inlabel : conf->lsm_aa_profile;
char *curlabel;

Expand Down Expand Up @@ -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;
}

Expand Down
91 changes: 90 additions & 1 deletion src/lxc/lsm/lsm.c
Expand Up @@ -85,8 +85,97 @@ 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_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,
int use_default, int on_exec)
bool use_default, bool on_exec)
{
if (!drv) {
ERROR("LSM driver not inited");
Expand Down

0 comments on commit 26f0e91

Please sign in to comment.