int sestatus_main(int argc, char **argv) { unsigned opts; const char *pol_path; int rc; opt_complementary = "?0"; /* no arguments are required. */ opts = getopt32(argv, "vb"); /* SELinux status: line */ rc = is_selinux_enabled(); if (rc < 0) goto error; printf(COL_FMT "%s\n", "SELinux status:", rc == 1 ? "enabled" : "disabled"); /* SELinuxfs mount: line */ if (!selinux_mnt) goto error; printf(COL_FMT "%s\n", "SELinuxfs mount:", selinux_mnt); /* Current mode: line */ rc = security_getenforce(); if (rc < 0) goto error; printf(COL_FMT "%s\n", "Current mode:", rc == 0 ? "permissive" : "enforcing"); /* Mode from config file: line */ if (selinux_getenforcemode(&rc) != 0) goto error; printf(COL_FMT "%s\n", "Mode from config file:", rc < 0 ? "disabled" : (rc == 0 ? "permissive" : "enforcing")); /* Policy version: line */ rc = security_policyvers(); if (rc < 0) goto error; printf(COL_FMT "%u\n", "Policy version:", rc); /* Policy from config file: line */ pol_path = selinux_policy_root(); if (!pol_path) goto error; printf(COL_FMT "%s\n", "Policy from config file:", bb_basename(pol_path)); if (opts & OPT_BOOLEAN) display_boolean(); if (opts & OPT_VERBOSE) display_verbose(); return 0; error: bb_perror_msg_and_die("libselinux returns unknown state"); }
int main(int argc, char **argv) { /* these vars are reused several times */ int rc, opt, i, c; char *context, *root_path; /* files that need context checks */ char *fc[MAX_CHECK]; char *cterm = ttyname(0); int nfc = 0; struct stat m; /* processes that need context checks */ char *pc[MAX_CHECK]; int npc = 0; /* booleans */ char **bools; int nbool; int verbose = 0; int show_bools = 0; /* policy */ const char *pol_name, *root_dir; char *pol_path; while (1) { opt = getopt(argc, argv, "vb"); if (opt == -1) break; switch (opt) { case 'v': verbose = 1; break; case 'b': show_bools = 1; break; default: /* invalid option */ printf("\nUsage: %s [OPTION]\n\n", basename(argv[0])); printf(" -v Verbose check of process and file contexts.\n"); printf(" -b Display current state of booleans.\n"); printf("\nWithout options, show SELinux status.\n"); return -1; } } printf_tab("SELinux status:"); rc = is_selinux_enabled(); switch (rc) { case 1: printf("enabled\n"); break; case 0: printf("disabled\n"); return 0; break; default: printf("unknown (%s)\n", strerror(errno)); return 0; break; } printf_tab("SELinuxfs mount:"); if (selinux_mnt != NULL) { printf("%s\n", selinux_mnt); } else { printf("not mounted\n\n"); printf("Please mount selinuxfs for proper results.\n"); return -1; } printf_tab("SELinux root directory:"); root_dir = selinux_path(); if (root_dir == NULL) { printf("error (%s)\n", strerror(errno)); return -1; } /* The path has a trailing '/' so duplicate to edit */ root_path = strdup(root_dir); if (!root_path) { printf("malloc error (%s)\n", strerror(errno)); return -1; } /* actually blank the '/' */ root_path[strlen(root_path) - 1] = '\0'; printf("%s\n", root_path); free(root_path); /* Dump all the path information */ printf_tab("Loaded policy name:"); pol_path = strdup(selinux_policy_root()); if (pol_path) { pol_name = basename(pol_path); puts(pol_name); free(pol_path); } else { printf("error (%s)\n", strerror(errno)); } printf_tab("Current mode:"); rc = security_getenforce(); switch (rc) { case 1: printf("enforcing\n"); break; case 0: printf("permissive\n"); break; default: printf("unknown (%s)\n", strerror(errno)); break; } printf_tab("Mode from config file:"); if (selinux_getenforcemode(&rc) == 0) { switch (rc) { case 1: printf("enforcing\n"); break; case 0: printf("permissive\n"); break; case -1: printf("disabled\n"); break; } } else { printf("error (%s)\n", strerror(errno)); } printf_tab("Policy MLS status:"); rc = is_selinux_mls_enabled(); switch (rc) { case 0: printf("disabled\n"); break; case 1: printf("enabled\n"); break; default: printf("error (%s)\n", strerror(errno)); break; } printf_tab("Policy deny_unknown status:"); rc = security_deny_unknown(); switch (rc) { case 0: printf("allowed\n"); break; case 1: printf("denied\n"); break; default: printf("error (%s)\n", strerror(errno)); break; } rc = security_policyvers(); printf_tab("Max kernel policy version:"); if (rc < 0) printf("unknown (%s)\n", strerror(errno)); else printf("%d\n", rc); if (show_bools) { /* show booleans */ if (security_get_boolean_names(&bools, &nbool) >= 0) { printf("\nPolicy booleans:\n"); for (i = 0; i < nbool; i++) { if (strlen(bools[i]) + 1 > COL) COL = strlen(bools[i]) + 1; } for (i = 0; i < nbool; i++) { printf_tab(bools[i]); rc = security_get_boolean_active(bools[i]); switch (rc) { case 1: printf("on"); break; case 0: printf("off"); break; default: printf("unknown (%s)", strerror(errno)); break; } c = security_get_boolean_pending(bools[i]); if (c != rc) switch (c) { case 1: printf(" (activate pending)"); break; case 0: printf(" (inactivate pending)"); break; default: printf(" (pending error: %s)", strerror(errno)); break; } printf("\n"); /* free up the booleans */ free(bools[i]); } free(bools); } } /* only show contexts if -v is given */ if (!verbose) return 0; load_checks(pc, &npc, fc, &nfc); printf("\nProcess contexts:\n"); printf_tab("Current context:"); if (getcon(&context) >= 0) { printf("%s\n", context); freecon(context); } else printf("unknown (%s)\n", strerror(errno)); printf_tab("Init context:"); if (getpidcon(1, &context) >= 0) { printf("%s\n", context); freecon(context); } else printf("unknown (%s)\n", strerror(errno)); for (i = 0; i < npc; i++) { rc = pidof(pc[i]); if (rc > 0) { if (getpidcon(rc, &context) < 0) continue; printf_tab(pc[i]); printf("%s\n", context); freecon(context); } } printf("\nFile contexts:\n"); /* controlling term */ printf_tab("Controlling terminal:"); if (lgetfilecon(cterm, &context) >= 0) { printf("%s\n", context); freecon(context); } else { printf("unknown (%s)\n", strerror(errno)); } for (i = 0; i < nfc; i++) { if (lgetfilecon(fc[i], &context) >= 0) { printf_tab(fc[i]); /* check if this is a symlink */ if (lstat(fc[i], &m)) { printf ("%s (could not check link status (%s)!)\n", context, strerror(errno)); freecon(context); continue; } if (S_ISLNK(m.st_mode)) { /* print link target context */ printf("%s -> ", context); freecon(context); if (getfilecon(fc[i], &context) >= 0) { printf("%s\n", context); freecon(context); } else { printf("unknown (%s)\n", strerror(errno)); } } else { printf("%s\n", context); freecon(context); } } } return 0; }
/* * Mount point for selinuxfs. * This definition is private to the function below. * Everything else uses the location determined during * libselinux startup via /proc/mounts (see init_selinuxmnt). * We only need the hardcoded definition for the initial mount * required for the initial policy load. */ int selinux_init_load_policy(int *enforce) { int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1; FILE *cfg; char *buf; /* * Reread the selinux configuration in case it has changed. * Example: Caller has chroot'd and is now loading policy from * chroot'd environment. */ selinux_reset_config(); /* * Get desired mode (disabled, permissive, enforcing) from * /etc/selinux/config. */ selinux_getenforcemode(&seconfig); /* Check for an override of the mode via the kernel command line. */ rc = mount("proc", "/proc", "proc", 0, 0); cfg = fopen("/proc/cmdline", "r"); if (cfg) { char *tmp; buf = malloc(selinux_page_size); if (!buf) { fclose(cfg); return -1; } if (fgets(buf, selinux_page_size, cfg) && (tmp = strstr(buf, "enforcing="))) { if (tmp == buf || isspace(*(tmp - 1))) { secmdline = atoi(tmp + sizeof("enforcing=") - 1); } } fclose(cfg); free(buf); } #ifndef MNT_DETACH #define MNT_DETACH 2 #endif if (rc == 0) umount2("/proc", MNT_DETACH); /* * Determine the final desired mode. * Command line argument takes precedence, then config file. */ if (secmdline >= 0) *enforce = secmdline; else if (seconfig >= 0) *enforce = seconfig; else *enforce = 0; /* unspecified or disabled */ /* * Check for the existence of SELinux via selinuxfs, and * mount it if present for use in the calls below. */ if (mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, 0) < 0 && errno != EBUSY) { if (errno == ENODEV) { /* * SELinux was disabled in the kernel, either * omitted entirely or disabled at boot via selinux=0. * This takes precedence over any config or * commandline enforcing setting. */ *enforce = 0; } else { /* Only emit this error if selinux was not disabled */ fprintf(stderr, "Mount failed for selinuxfs on %s: %s\n", SELINUXMNT, strerror(errno)); } goto noload; } set_selinuxmnt(SELINUXMNT); /* * Note: The following code depends on having selinuxfs * already mounted and selinuxmnt set above. */ if (seconfig == -1) { /* Runtime disable of SELinux. */ rc = security_disable(); if (rc == 0) { /* Successfully disabled, so umount selinuxfs too. */ umount(SELINUXMNT); fini_selinuxmnt(); } /* * If we failed to disable, SELinux will still be * effectively permissive, because no policy is loaded. * No need to call security_setenforce(0) here. */ goto noload; } /* * If necessary, change the kernel enforcing status to match * the desired mode. */ orig_enforce = rc = security_getenforce(); if (rc < 0) goto noload; if (orig_enforce != *enforce) { rc = security_setenforce(*enforce); if (rc < 0) { fprintf(stderr, "SELinux: Unable to switch to %s mode: %s\n", (*enforce ? "enforcing" : "permissive"), strerror(errno)); if (*enforce) goto noload; } } /* Load the policy. */ return selinux_mkload_policy(0); noload: /* * Only return 0 on a successful completion of policy load. * In any other case, we want to return an error so that init * knows not to proceed with the re-exec for the domain transition. * Depending on the *enforce setting, init will halt (> 0) or proceed * normally (otherwise). */ return -1; }