mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-15 06:06:57 +00:00
Merge pull request #2102 from brauner/2018-01-22/lsm_simplifications
lsm: simplifcations
This commit is contained in:
commit
26f0e9151a
@ -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]])],
|
||||
|
@ -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)
|
||||
@ -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
|
||||
|
113
src/lxc/attach.c
113
src/lxc/attach.c
@ -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)
|
||||
@ -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 &&
|
||||
@ -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);
|
||||
|
@ -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"
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -28,29 +28,66 @@ 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);
|
||||
char *(*process_label_get)(pid_t pid);
|
||||
int (*process_label_set)(const char *label, struct lxc_conf *conf,
|
||||
int use_default, int on_exec);
|
||||
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);
|
||||
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) { }
|
||||
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 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, int use_default, int on_exec) { return 0; }
|
||||
struct lxc_conf *conf, bool use_default,
|
||||
bool on_exec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -565,4 +565,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 */
|
||||
|
Loading…
Reference in New Issue
Block a user