Re: Proposed patch for policycoreutils/sestatus

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

On Thu, 17 Jul 2008, Joshua Brindle wrote:

> split the layout changes from the functional changes and
> submit 2 patches please.

All right, here they come, I hope they are okay now.

Please apply the patches in this order:

  1) sestatus-layout.patch
  2) sestatus-functionality.patch

Best regards,
vmk
-- 
************************************************************************
               Tietotekniikkaosasto / Helsingin yliopisto
                 IT Department / University of Helsinki
************************************************************************
--- policycoreutils-2.0.46/sestatus/sestatus.c	2008-03-18 22:57:01.000000000 +0200
+++ policycoreutils-2.0.46-vmk/sestatus/sestatus.c	2008-07-17 18:46:39.000000000 +0300
@@ -3,20 +3,22 @@
  * Distributed under the terms of the GNU General Public License v2
  * $Header: /home/cvsroot/gentoo-projects/hardened/policycoreutils-extra/src/sestatus.c,v 1.10 2004/03/26 19:25:52 pebenito Exp $
  * Patch provided by Steve Grubb
+ * Refactored by Vesa-Matti Kari
  */
 
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <libgen.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <errno.h>
-#include <selinux/selinux.h>
-#include <selinux/get_default_type.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
 #include <unistd.h>
-#include <libgen.h>
-#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <selinux/get_default_type.h>
+#include <selinux/selinux.h>
 
 #define PROC_BASE "/proc"
 #define MAX_CHECK 50
@@ -60,7 +62,6 @@
 
 int pidof(const char *command)
 {
-/* inspired by killall5.c from psmisc */
 	DIR *dir;
 	struct dirent *de;
 	int pid, ret = -1, self = getpid();
@@ -169,82 +170,44 @@
 
 }
 
-int main(int argc, char **argv)
+static int status_show(void)
 {
-	/* these vars are reused several times */
-	int rc, opt, i, c;
-	char *context;
-
-	/* 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;
-	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("\nWithout options, show SELinux status.\n");
-			return -1;
-		}
-	}
 	printf_tab("SELinux status:");
-	rc = is_selinux_enabled();
 
-	switch (rc) {
+	switch (is_selinux_enabled()) {
 	case 1:
 		printf("enabled\n");
+		return 1;
 		break;
 	case 0:
 		printf("disabled\n");
 		return 0;
 		break;
 	default:
-		printf("unknown (%s)\n", strerror(errno));
+		printf("unknown (%s)\n", strerror(errno)); 
 		return 0;
 		break;
 	}
+}
 
+static int mount_show(const char *mnt)
+{
 	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;
-	}
 
+	if (mnt) {
+		printf("%s\n", mnt);
+		return 0;
+	} 
+
+	fprintf(stderr, "not mounted\n\nPlease mount selinuxfs for proper results.\n");
+	return -1;
+}
+
+static void mode_show(void)
+{
 	printf_tab("Current mode:");
-	rc = security_getenforce();
-	switch (rc) {
+
+	switch (security_getenforce()) {
 	case 1:
 		printf("enforcing\n");
 		break;
@@ -255,8 +218,14 @@
 		printf("unknown (%s)\n", strerror(errno));
 		break;
 	}
+}
+
+static void confmode_show(void)
+{
+	int rc;
 
 	printf_tab("Mode from config file:");
+
 	if (selinux_getenforcemode(&rc) == 0) {
 		switch (rc) {
 		case 1:
@@ -269,81 +238,98 @@
 			printf("disabled\n");
 			break;
 		}
-	} else {
+	} else
 		printf("error (%s)\n", strerror(errno));
-	}
+}
+
+static void policyvers_show(void)
+{
+	int rc;
 
-	rc = security_policyvers();
 	printf_tab("Policy version:");
+
+	rc = security_policyvers();
 	if (rc < 0)
 		printf("unknown (%s)\n", strerror(errno));
 	else
 		printf("%d\n", rc);
+}
+
+static void confpolicyvers_show(void)
+{
+	const char *pol_name;
+	char *pol_path;
 
-	/* Dump all the path information */
 	printf_tab("Policy from config file:");
+
 	pol_path = strdup(selinux_policy_root());
-	if (pol_path) {
-		pol_name = basename(pol_path);
-		puts(pol_name);
-		free(pol_path);
-	} else {
+	if (!pol_path) {
 		printf("error (%s)\n", strerror(errno));
+		return;
 	}
 
-	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]);
+	pol_name = basename(pol_path);
+	puts(pol_name);
+	free(pol_path);
+}
 
-				rc = security_get_boolean_active(bools[i]);
-				switch (rc) {
+static void bools_show(unsigned int *column)
+{
+	char **bools;
+	int nbool;
+	int c, i, rc;
+
+	rc = security_get_boolean_names(&bools, &nbool);
+	if (rc < 0)
+		return;
+
+	printf("Policy booleans:\n");
+
+		for (i = 0; i < nbool; i++)
+			if (strlen(bools[i]) + 1 > *column)
+				*column = 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("on");
+					printf(" (activate pending)");
 					break;
 				case 0:
-					printf("off");
+					printf(" (inactivate pending)");
 					break;
 				default:
-					printf("unknown (%s)", strerror(errno));
+					printf(" (pending error: %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");
+			printf("\n");
 
-				/* free up the booleans */
-				free(bools[i]);
-			}
-			free(bools);
+			free(bools[i]);
 		}
-	}
-	/* only show contexts if -v is given */
-	if (!verbose)
-		return 0;
+		free(bools);
+}
 
-	load_checks(pc, &npc, fc, &nfc);
+static void proccon_show(char *pc[], int npc)
+{
+	char *context;
+	int i, rc;
 
-	printf("\nProcess contexts:\n");
+	printf("Process contexts:\n");
 
 	printf_tab("Current context:");
 	if (getcon(&context) >= 0) {
@@ -371,10 +357,22 @@
 		}
 	}
 
-	printf("\nFile contexts:\n");
+	for (i = 0; i < npc; i++)
+		free(pc[i]);
+}
+
+static void filecon_show(char *fc[], int nfc)
+{
+	struct stat st;
+	char *context;
+	char *cterm;
+	int i;
+
+	printf("File contexts:\n");
 
-	/* controlling term */
 	printf_tab("Controlling term:");
+
+	cterm = ttyname(0);
 	if (lgetfilecon(cterm, &context) >= 0) {
 		printf("%s\n", context);
 		freecon(context);
@@ -387,14 +385,13 @@
 			printf_tab(fc[i]);
 
 			/* check if this is a symlink */
-			if (lstat(fc[i], &m)) {
-				printf
-				    ("%s (could not check link status (%s)!)\n",
+			if (lstat(fc[i], &st)) {
+				printf ("%s (could not check link status (%s)!)\n",
 				     context, strerror(errno));
 				freecon(context);
 				continue;
 			}
-			if (S_ISLNK(m.st_mode)) {
+			if (S_ISLNK(st.st_mode)) {
 				/* print link target context */
 				printf("%s -> ", context);
 				freecon(context);
@@ -402,16 +399,79 @@
 				if (getfilecon(fc[i], &context) >= 0) {
 					printf("%s\n", context);
 					freecon(context);
-				} else {
-					printf("unknown (%s)\n",
-					       strerror(errno));
-				}
+				} else 
+					printf("unknown (%s)\n", strerror(errno));
 			} else {
 				printf("%s\n", context);
 				freecon(context);
 			}
+		} 
+	}
+
+	for (i = 0; i < nfc; i++)
+		free(fc[i]);
+}
+
+int main(int argc, char *argv[])
+{
+	char *pc[MAX_CHECK]; /* processes that need context checks */
+	char *fc[MAX_CHECK]; /* files that need context checks */
+	int npc, nfc;
+	int verbose, bools;
+	int rc, opt;
+
+	npc = nfc = 0;
+	verbose = bools = 0;
+
+	while (1) {
+		opt = getopt(argc, argv, "vb");
+		if (opt == -1)
+			break;
+		switch (opt) {
+		case 'v':
+			verbose = 1;
+			break;
+		case 'b':
+			bools = 1;
+			break;
+		default:
+			fprintf(stderr, "\nUsage: %s [OPTION]\n\n", basename(argv[0]));
+			fprintf(stderr, "  -v  Verbose check of process and file contexts.\n");
+			fprintf(stderr, "\nWithout options, show SELinux status.\n");
+			return -1;
 		}
 	}
 
+	rc = status_show();
+	if (rc < 1) {
+		return rc;
+	}
+
+	rc = mount_show(selinux_mnt);
+	if (rc < 0) {
+		return rc;
+	}
+
+	mode_show();
+	confmode_show();
+	policyvers_show();
+	confpolicyvers_show();
+
+	if (bools) {
+		putchar('\n');
+		bools_show(&COL);
+	}
+
+	if (!verbose)
+		return 0;
+
+	load_checks(pc, &npc, fc, &nfc);
+
+	putchar('\n');
+	proccon_show(pc, npc);
+
+	putchar('\n');
+	filecon_show(fc, nfc);
+
 	return 0;
 }
--- policycoreutils-2.0.46/sestatus/sestatus.c	2008-07-17 18:51:41.000000000 +0300
+++ policycoreutils-2.0.46-vmk/sestatus/sestatus.c	2008-07-17 18:45:11.000000000 +0300
@@ -20,152 +20,156 @@
 #include <selinux/get_default_type.h>
 #include <selinux/selinux.h>
 
+
 #define PROC_BASE "/proc"
 #define MAX_CHECK 50
 #define CONF "/etc/sestatus.conf"
+#define INIT_PROC_PID (pid_t)1
 
 /* conf file sections */
 #define PROCS "[process]"
 #define FILES "[files]"
 
-/* buffer size for cmp_cmdline */
+/* buffer size for cmp_cmdline() and load_checks() */
 #define BUFSIZE 255
 
+
 /* column to put the output (must be a multiple of 8) */
 static unsigned int COL = 32;
 
 extern char *selinux_mnt;
 
-int cmp_cmdline(const char *command, int pid)
-{
 
+static int cmp_cmdline(const char *command, pid_t pid)
+{
 	char buf[BUFSIZE];
 	char filename[BUFSIZE];
 
-	memset(buf, '\0', BUFSIZE);
+	memset(buf, '\0', sizeof buf);
 
-	/* first read the proc entry */
-	sprintf(filename, "%s/%d/exe", PROC_BASE, pid);
+	snprintf(filename, sizeof filename, "%s/%d/exe", PROC_BASE, pid);
 
-	if (readlink(filename, buf, BUFSIZE) < 0)
+	if (readlink(filename, buf, sizeof buf) < 0)
 		return 0;
 
-	if (buf[BUFSIZE - 1] != '\0')
-		buf[BUFSIZE - 1] = '\0';
+	if (buf[sizeof buf - 1] != '\0')
+		buf[sizeof buf - 1] = '\0';
 
-	/* check if this is the command we're looking for. */
-	if (strcmp(command, buf) == 0)
-		return 1;
-	else
-		return 0;
+	return !strcmp(command, buf);
 }
 
-int pidof(const char *command)
+static int pidof(const char *command, pid_t *pid)
 {
 	DIR *dir;
 	struct dirent *de;
-	int pid, ret = -1, self = getpid();
+	pid_t self;
+	int rc;
+
+	rc = -1;
 
-	if (!(dir = opendir(PROC_BASE))) {
-		perror(PROC_BASE);
-		return -1;
+	dir = opendir(PROC_BASE);
+	if (!dir) {
+		fprintf(stderr, "Unable to open %s: %s", PROC_BASE, strerror(errno));
+		return rc;
 	}
 
-	while ((de = readdir(dir)) != NULL) {
+	self = getpid();
+	while ((de = readdir(dir))) {
 		errno = 0;
-		pid = (int)strtol(de->d_name, (char **)NULL, 10);
-		if (errno || pid == 0 || pid == self)
+		*pid = (pid_t)strtol(de->d_name, NULL, 10);
+		if (errno || *pid == 0 || *pid == self)
 			continue;
-		if (cmp_cmdline(command, pid)) {
-			ret = pid;
+		if (cmp_cmdline(command, *pid)) {
+			rc = 0;
 			break;
 		}
 	}
 
 	closedir(dir);
-	return ret;
+	return rc;
 }
 
-void load_checks(char *pc[], int *npc, char *fc[], int *nfc)
+static void load_checks(char *pc[], int *npc, char *fc[], int *nfc)
 {
+	FILE *fp;
+	char buf[BUFSIZE];
+	char *bufp;
+	int buflen, section;
+	int i;
 
-	FILE *fp = fopen(CONF, "r");
-	char buf[255], *bufp;
-	int buf_len, section = -1;
-	int proclen = strlen(PROCS);
-	int filelen = strlen(FILES);
-
-	if (fp == NULL) {
-		printf("\nUnable to open %s.\n", CONF);
+	fp = fopen(CONF, "r");
+	if (!fp) {
+		fprintf(stderr, "\nUnable to open %s: %s\n", CONF, strerror(errno));
 		return;
 	}
 
-	while (!feof(fp)) {
-		if (!fgets(buf, sizeof buf, fp))
-			break;
+	section = -1;
+
+	while (fgets(buf, sizeof buf, fp)) {
 
-		buf_len = strlen(buf);
-		if (buf[buf_len - 1] == '\n')
-			buf[buf_len - 1] = 0;
+		buflen = strlen(buf);
+		if (buf[buflen - 1] == '\n')
+			buf[buflen - 1] = '\0';
 
 		bufp = buf;
-		while (*bufp && isspace(*bufp)) {
+		while (*bufp && isspace(*bufp))
 			bufp++;
-			buf_len--;
-		}
 
-		if (*bufp == '#')
-			/* skip comments */
+		if (*bufp == '#' || *bufp == '\0')
 			continue;
 
-		if (*bufp) {
-			if (!(*bufp))
-				goto out;
-
-			if (strncmp(bufp, PROCS, proclen) == 0)
-				section = 0;
-			else if (strncmp(bufp, FILES, filelen) == 0)
-				section = 1;
-			else {
-				switch (section) {
-				case 0:
-					if (*npc >= MAX_CHECK)
-						break;
-					pc[*npc] =
-					    (char *)malloc((buf_len) *
-							   sizeof(char));
-					memcpy(pc[*npc], bufp, buf_len);
-					(*npc)++;
-					bufp = NULL;
-					break;
-				case 1:
-					if (*nfc >= MAX_CHECK)
-						break;
-					fc[*nfc] =
-					    (char *)malloc((buf_len) *
-							   sizeof(char));
-					memcpy(fc[*nfc], bufp, buf_len);
-					(*nfc)++;
-					bufp = NULL;
+		if (!strncmp(bufp, PROCS, sizeof PROCS))
+			section = 0;
+		else if (!strncmp(bufp, FILES, sizeof FILES))
+			section = 1;
+		else {
+			switch (section) {
+			case 0:
+				if (*npc >= MAX_CHECK)
 					break;
-				default:
-					/* ignore lines before a section */
-					printf("Line not in a section: %s.\n",
-					       buf);
+				pc[*npc] = strdup(bufp);
+				if (!pc[*npc])
+					goto outfree;
+				(*npc)++;
+				break;
+			case 1:
+				if (*nfc >= MAX_CHECK)
 					break;
-				}
+				fc[*nfc] = strdup(bufp);
+				if (!fc[*nfc]) 
+					goto outfree;
+				(*nfc)++;
+				break;
+			default:
+				/* ignore lines before a section */
+				printf("Line not in a section: %s.\n", buf);
+				break;
 			}
 		}
 	}
-      out:
+
+	if (ferror(fp)) {
+		fprintf(stderr, "\nError while reading %s: %s\n", CONF, strerror(errno));
+		goto outfree;
+	}
+
+out:
 	fclose(fp);
 	return;
+
+outfree:
+	for (i = 0; i < *npc && i < MAX_CHECK; i++)
+		free(pc[i]);
+	for (i = 0; i < *nfc && i < MAX_CHECK; i++)
+		free(fc[i]);
+	*npc = *nfc = 0;
+	goto out;
 }
 
-void printf_tab(const char *outp)
+static void printf_tab(const char *outp)
 {
 	char buf[20];
-	snprintf(buf, sizeof(buf), "%%-%us", COL);
+	snprintf(buf, sizeof buf, "%%-%us", COL);
 	printf(buf, outp);
 
 }
@@ -327,6 +331,7 @@
 static void proccon_show(char *pc[], int npc)
 {
 	char *context;
+	pid_t pid;
 	int i, rc;
 
 	printf("Process contexts:\n");
@@ -339,22 +344,24 @@
 		printf("unknown (%s)\n", strerror(errno));
 
 	printf_tab("Init context:");
-	if (getpidcon(1, &context) >= 0) {
+	if (getpidcon(INIT_PROC_PID, &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;
+		rc = pidof(pc[i], &pid);
 
-			printf_tab(pc[i]);
-			printf("%s\n", context);
-			freecon(context);
-		}
+		if (rc < 0)
+			continue;
+
+		if (getpidcon(pid, &context) < 0)
+			continue;
+
+		printf_tab(pc[i]);
+		printf("%s\n", context);
+		freecon(context);
 	}
 
 	for (i = 0; i < npc; i++)
@@ -365,20 +372,23 @@
 {
 	struct stat st;
 	char *context;
-	char *cterm;
+	char *ctrlterm;
 	int i;
 
 	printf("File contexts:\n");
 
 	printf_tab("Controlling term:");
 
-	cterm = ttyname(0);
-	if (lgetfilecon(cterm, &context) >= 0) {
-		printf("%s\n", context);
-		freecon(context);
-	} else {
-		printf("unknown (%s)\n", strerror(errno));
-	}
+	ctrlterm = ttyname(STDIN_FILENO);
+	if (ctrlterm) {
+		if (lgetfilecon(ctrlterm, &context) >= 0) {
+			printf("%s\n", context);
+			freecon(context);
+		} else {
+			printf("unknown (%s)\n", strerror(errno));
+		}
+	} else
+		printf("error: %s\n", strerror(errno));
 
 	for (i = 0; i < nfc; i++) {
 		if (lgetfilecon(fc[i], &context) >= 0) {
@@ -436,6 +446,7 @@
 			break;
 		default:
 			fprintf(stderr, "\nUsage: %s [OPTION]\n\n", basename(argv[0]));
+			fprintf(stderr, "  -b  Display the current state of booleans.\n");
 			fprintf(stderr, "  -v  Verbose check of process and file contexts.\n");
 			fprintf(stderr, "\nWithout options, show SELinux status.\n");
 			return -1;
#!/bin/bash
#
# PURPOSE: compare old and new sestatus output
# NOTE: run this in policycoreutils-X-Y-ZZ/sestatus


OLD=/usr/sbin/sestatus
NEW=$PWD/sestatus

OOUT=/tmp/old
NOUT=/tmp/new

i=0
for arg in '' '-b' '-v' '-vb'; do
	((i++))
	echo -n "$OLD $arg => "
	$OLD $arg > $OOUT &&
	$NEW $arg > $NOUT &&
	diff $OOUT $NOUT &&
	echo test $i okay ||
	echo test $i failed
done

rm -f $OOUT $NOUT

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux