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)
}
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 &&
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)
{
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)
{
{
return 0;
}
+
+extern int lsm_process_label_set_at(int label_fd, const char *label,
+ bool on_exec)
+{
+ return 0;
+}
#endif
#endif