/** * Verify that the config mode is compatible with the kernel's AppArmor * support. If AppArmor mediation will be enabled, determine the bus * confinement label. */ dbus_bool_t bus_apparmor_full_init (DBusError *error) { #ifdef HAVE_APPARMOR char *label, *mode; if (apparmor_enabled) { if (apparmor_config_mode == APPARMOR_DISABLED) { apparmor_enabled = FALSE; return TRUE; } if (bus_con == NULL) { if (aa_getcon (&label, &mode) == -1) { dbus_set_error (error, DBUS_ERROR_FAILED, "Error getting AppArmor context of bus: %s", _dbus_strerror (errno)); return FALSE; } bus_con = bus_apparmor_confinement_new (label, mode); if (bus_con == NULL) { BUS_SET_OOM (error); free (label); return FALSE; } } } else { if (apparmor_config_mode == APPARMOR_REQUIRED) { dbus_set_error (error, DBUS_ERROR_FAILED, "AppArmor mediation required but not present"); return FALSE; } else if (apparmor_config_mode == APPARMOR_ENABLED) { return TRUE; } } #endif return TRUE; }
int fpm_unix_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ { int is_root = !geteuid(); int made_chroot = 0; if (wp->config->rlimit_files) { struct rlimit r; r.rlim_max = r.rlim_cur = (rlim_t) wp->config->rlimit_files; if (0 > setrlimit(RLIMIT_NOFILE, &r)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to set rlimit_files for this pool. Please check your system limits or decrease rlimit_files. setrlimit(RLIMIT_NOFILE, %d)", wp->config->name, wp->config->rlimit_files); } } if (wp->config->rlimit_core) { struct rlimit r; r.rlim_max = r.rlim_cur = wp->config->rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) wp->config->rlimit_core; if (0 > setrlimit(RLIMIT_CORE, &r)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to set rlimit_core for this pool. Please check your system limits or decrease rlimit_core. setrlimit(RLIMIT_CORE, %d)", wp->config->name, wp->config->rlimit_core); } } if (is_root && wp->config->chroot && *wp->config->chroot) { if (0 > chroot(wp->config->chroot)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to chroot(%s)", wp->config->name, wp->config->chroot); return -1; } made_chroot = 1; } if (wp->config->chdir && *wp->config->chdir) { if (0 > chdir(wp->config->chdir)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to chdir(%s)", wp->config->name, wp->config->chdir); return -1; } } else if (made_chroot) { if (0 > chdir("/")) { zlog(ZLOG_WARNING, "[pool %s] failed to chdir(/)", wp->config->name); } } if (is_root) { if (wp->config->process_priority != 64) { if (setpriority(PRIO_PROCESS, 0, wp->config->process_priority) < 0) { zlog(ZLOG_SYSERROR, "[pool %s] Unable to set priority for this new process", wp->config->name); return -1; } } if (wp->set_gid) { if (0 > setgid(wp->set_gid)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to setgid(%d)", wp->config->name, wp->set_gid); return -1; } } if (wp->set_uid) { if (0 > initgroups(wp->config->user, wp->set_gid)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to initgroups(%s, %d)", wp->config->name, wp->config->user, wp->set_gid); return -1; } if (0 > setuid(wp->set_uid)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to setuid(%d)", wp->config->name, wp->set_uid); return -1; } } } #ifdef HAVE_PRCTL if (0 > prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to prctl(PR_SET_DUMPABLE)", wp->config->name); } #endif if (0 > fpm_clock_init()) { return -1; } #ifdef HAVE_APPARMOR if (wp->config->apparmor_hat) { char *con, *new_con; if (aa_getcon(&con, NULL) == -1) { zlog(ZLOG_SYSERROR, "[pool %s] failed to query apparmor confinement. Please check if \"/proc/*/attr/current\" is read and writeable.", wp->config->name); return -1; } new_con = malloc(strlen(con) + strlen(wp->config->apparmor_hat) + 3); // // + 0 Byte if (!new_con) { zlog(ZLOG_SYSERROR, "[pool %s] failed to allocate memory for apparmor hat change.", wp->config->name); return -1; } if (0 > sprintf(new_con, "%s//%s", con, wp->config->apparmor_hat)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to construct apparmor confinement.", wp->config->name); return -1; } if (0 > aa_change_profile(new_con)) { zlog(ZLOG_SYSERROR, "[pool %s] failed to change to new confinement (%s). Please check if \"/proc/*/attr/current\" is read and writeable and \"change_profile -> %s//*\" is allowed.", wp->config->name, new_con, con); return -1; } free(con); free(new_con); } #endif return 0; }
int main(int argc, char *argv[]) { int rc; char *profile, *mode; if (argc < 3 || argc > 4) { fprintf(stderr, "usage: %s <task> <expected profile> [<expect mode>]\n", argv[0]); return 1; } if (strcmp(argv[1], "self") == 0){ rc = aa_getcon(&profile, &mode); if (rc == -1) { int serrno = errno; fprintf(stderr, "FAIL: introspect_confinement %s failed - %s\n", argv[1], strerror(errno)); exit(serrno); } } else { char *end; pid_t pid = strtol(argv[1], &end, 10); if (end == argv[1] || *end != 0) { int serrno = errno; fprintf(stderr, "FAIL: query_confinement - invalid pid: %s\n", argv[1]); exit(serrno); } else { rc = aa_gettaskcon(pid, &profile, &mode); if (rc == -1) { int serrno = errno; fprintf(stderr, "FAIL: query_confinement %s failed - %s\n", argv[1], strerror(errno)); exit(serrno); } } } if (strcmp(profile, argv[2]) != 0) { fprintf(stderr, "FAIL: expected confinement \"%s\" != \"%s\"\n", argv[2], profile); exit(1); } if (mode) { if (rc != strlen(profile) + strlen(mode) + 4) { /* rc includes mode. + 2 null term + 1 ( + 1 space */ fprintf(stderr, "FAIL: expected return len %zd != actual %d\n", strlen(profile) + strlen(mode) + 4, rc); exit(1); } } else if (rc != strlen(profile) + 1) { /* rc includes null termination */ fprintf(stderr, "FAIL: expected return len %zd != actual %d\n", strlen(profile) + 1, rc); exit(1); } if (argv[3] && (!mode || strcmp(mode, argv[3]) != 0)) { fprintf(stderr, "FAIL: expected mode \"%s\" != \"%s\"\n", argv[3], mode ? mode : "(null)"); exit(1); } free(profile); printf("PASS\n"); return 0; }