Re: initial_sid context via libsepol

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

 






On Friday, 4 March 2016, 21:18, "Roberts, William C" <william.c.roberts@xxxxxxxxx> wrote:


>
>
> 
> 
>How can one obtain the same value as /sys/fs/selinux/initial_contexts/file via libsepol?
> 
>I’ve been digging around libsepol and its not quite clear to me.
> 
>It looks as though the record is here:
>                context_struct_t *a = &((policydb_t *)pol.db)->ocontexts[OCON_ISID]->context[0];
>                context_struct_t *b = &((policydb_t *)pol.db)->ocontexts[OCON_ISID]->context[1];
> 
>                printf("%u\n", a->type);
>                printf("%u\n",b->type);
> 
>Prints:
>185
>0
> 
>Not sure if this is right, and how to format the context struct to a string. I didn’t see any helpers.
>

>
I've attached an example, hope it's useful
>
> 
>Thanks,
>Bill
>_______________________________________________
>Selinux mailing list
>Selinux@xxxxxxxxxxxxx
>To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
>To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.
>
>
/* gcc display-initial-sid-info.c -o display-initial-sid-info -lselinux /usr/lib64/libsepol.a */

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sepol/policydb/policydb.h>

/* load_policy taken from sepolicy-analyze.c */
int load_policy(char *filename, policydb_t *policydb, struct policy_file *pf)
{
	int fd;
	struct stat sb;
	void *map;
	int ret;

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Can't open '%s':  %s\n", filename, strerror(errno));
		return 1;
	}
	if (fstat(fd, &sb) < 0) {
		fprintf(stderr, "Can't stat '%s':  %s\n", filename, strerror(errno));
		close(fd);
		return 1;
	}
	map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
	if (map == MAP_FAILED) {
		fprintf(stderr, "Can't mmap '%s':  %s\n", filename, strerror(errno));
		close(fd);
		return 1;
	}

	policy_file_init(pf);
	pf->type = PF_USE_MEMORY;
	pf->data = map;
	pf->len = sb.st_size;
	if (policydb_init(policydb)) {
		fprintf(stderr, "Could not initialize policydb!\n");
		close(fd);
		munmap(map, sb.st_size);
		return 1;
	}
	ret = policydb_read(policydb, pf, 0);
	if (ret) {
		fprintf(stderr, "error(s) encountered while parsing configuration\n");
		close(fd);
		munmap(map, sb.st_size);
		return 1;
	}
	return 0;
}

/* The initial SID names are not available when loading a binary policy.
 * They need to be taken from the policy 'initial_sids' file. However
 * they tend to be common so setools uses a table like this:
*/
static const char *const sidnames[] = {
	/* I've made them print neat & tidy, tidy & neat !!!*/
	"kernel         ",
	"security       ",
	"unlabeled      ",
	"fs             ",
	"file           ",
	"file_labels    ",
	"init           ",
	"any_socket     ",
	"port           ",
	"netif          ",
	"netmsg         ",
	"node           ",
	"igmp_packet    ",
	"icmp_socket    ",
	"tcp_socket     ",
	"sysctl_modprobe",
	"sysctl         ",
	"sysctl_fs      ",
	"sysctl_kernel  ",
	"sysctl_net     ",
	"sysctl_net_unix",
	"sysctl_vm      ",
	"sysctl_dev     ",
	"kmod           ",
	"policy         ",
	"scmp_packet    ",
	"devnull        "
};

/* This is reworked from libsepol/src/mls.c mls_compute_context_len() to print the MLS components.
 * Best seen on /etc/selinux/mls/policy/policy.29
 */
void mls_print(const policydb_t *policydb, ocontext_t *cur)
{
	unsigned int i, l, range;
	ebitmap_node_t *cnode;

	if (!policydb->mls)
		return;

	for (l = 0; l < 2; l++) {
		range = 0;
		printf(":%s", policydb->p_sens_val_to_name[cur->context[0].range.level[l].sens - 1]);

		ebitmap_for_each_bit(&cur->context[0].range.level[l].cat, cnode, i) {
			if (ebitmap_node_get_bit(cnode, i)) {
				if (range) {
					range++;
					continue;
				}

				printf(":%s", policydb->p_cat_val_to_name[i]);
				range++;
			} else {
				if (range > 1)
					printf(",%s",policydb->p_cat_val_to_name[i - 1]);

				range = 0;
			}
		}
		/* Handle case where last category is the end of range */
		if (range > 1)
			printf(".%s",policydb->p_cat_val_to_name[i - 1]);

		if (l == 0) {
			if (mls_level_eq(&cur->context[0].range.level[0], &cur->context[0].range.level[1]))
				break;
		}
	}
}

int main(int argc, char **argv)
{
	char *policy;
	struct policy_file pf;
	policydb_t policydb;
	ocontext_t *cur;
	int entry = 0;

	if (argc < 2) {
		printf("Need binary policy file:\n");
		printf("\t%s policy_file\n", argv[0]);
		exit(1);
	}

	policy = argv[1];
	if (load_policy(policy, &policydb, &pf))
		exit(1);

	/* Count entries */
	for (cur = policydb.ocontexts[OCON_ISID]; cur != NULL; cur = cur->next)
		entry++;

	printf("There are %d initial sids in the policy\n\n", entry);

	entry = 0;
	printf("SID  Name             Context\n");
	for (cur = policydb.ocontexts[OCON_ISID]; cur != NULL; cur = cur->next) {
		printf("%2d   %s  %s:%s:%s",
			    cur->sid[0],
			    sidnames[entry],
			    policydb.p_user_val_to_name[cur->context[0].user - 1],
			    policydb.p_role_val_to_name[cur->context[0].role - 1],
			    policydb.p_type_val_to_name[cur->context[0].type - 1]);

		mls_print(&policydb, cur);
		printf("\n");
		entry++;
	}

	exit(0);
}
_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.

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

  Powered by Linux