static int lsm_openat(int procfd, pid_t pid, int on_exec) { int ret = -1; int labelfd = -1; const char *name; char path[__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, __LSMATTRLEN, "%d/attr/exec", pid); else ret = snprintf(path, __LSMATTRLEN, "%d/attr/current", pid); if (ret < 0 || ret >= __LSMATTRLEN) return -1; labelfd = openat(procfd, path, O_RDWR); if (labelfd < 0) { SYSERROR("Unable to open file descriptor to set LSM label."); return -1; } return labelfd; }
static void test_lsm_detect(void) { if (lsm_enabled()) { if (!strcmp(lsm_name(), "SELinux")) { lsm_config_key = "lxc.se_context"; lsm_label = "unconfined_u:unconfined_r:lxc_t:s0-s0:c0.c1023"; } else if (!strcmp(lsm_name(), "AppArmor")) { lsm_config_key = "lxc.aa_profile"; lsm_label = "lxc-container-default"; } else { TSTERR("unknown lsm %s enabled, add test code here", lsm_name()); exit(EXIT_FAILURE); } } }
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; }
int lsm_set_label_at(int procfd, int on_exec, char* lsm_label) { int labelfd = -1; int ret = 0; const char* name; char* command = NULL; name = lsm_name(); if (strcmp(name, "nop") == 0) goto out; if (strcmp(name, "none") == 0) goto out; /* We don't support on-exec with AppArmor */ if (strcmp(name, "AppArmor") == 0) on_exec = 0; if (on_exec) { labelfd = openat(procfd, "self/attr/exec", O_RDWR); } else { labelfd = openat(procfd, "self/attr/current", O_RDWR); } if (labelfd < 0) { SYSERROR("Unable to open LSM label"); ret = -1; goto out; } if (strcmp(name, "AppArmor") == 0) { int size; command = malloc(strlen(lsm_label) + strlen("changeprofile ") + 1); if (!command) { SYSERROR("Failed to write apparmor profile"); ret = -1; goto out; } size = sprintf(command, "changeprofile %s", lsm_label); if (size < 0) { SYSERROR("Failed to write apparmor profile"); ret = -1; goto out; } if (write(labelfd, command, size + 1) < 0) { SYSERROR("Unable to set LSM label"); ret = -1; goto out; } } else if (strcmp(name, "SELinux") == 0) { if (write(labelfd, lsm_label, strlen(lsm_label) + 1) < 0) { SYSERROR("Unable to set LSM label"); ret = -1; goto out; } } else { ERROR("Unable to restore label for unknown LSM: %s", name); ret = -1; goto out; } out: free(command); if (labelfd != -1) close(labelfd); return ret; }