> On Saturday, 5 March 2016, 14:48, Richard Haines 
> <richard_c_hai...@btinternet.com> wrote:
> > 
> 
> 
> 
> On Friday, 4 March 2016, 21:18, "Roberts, William C" 
> <william.c.robe...@intel.com> 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

I've updated the example with more detail and display SID name using SID value 
not counter.
> 
>> 
>> 
>> Thanks,
>> Bill
>> _______________________________________________
>> Selinux mailing list
>> Selinux@tycho.nsa.gov
>> To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
>> To get help, send an email containing "help" to 
> selinux-requ...@tycho.nsa.gov.
>> 
>> 
> 
> _______________________________________________
> Selinux mailing list
> Selinux@tycho.nsa.gov
> To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
> To get help, send an email containing "help" to 
> selinux-requ...@tycho.nsa.gov.
>
/* gcc display-initial-sid-info.c -o display-initial-sid-info libsepol.a */

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.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 currently available in a binary policy (March '16).
 * They really need to be taken from the policy 'initial_sids' file. However for the
 * Reference Policy they tend to be common so setools uses a table like the one below.
 *
 * WARNING: If you have a custom kernel/policy that changes these, then update
 * this table (e.g. Xen has a different set as shown in the 'xen_sidnames' table).
 *
 * Note 1: The kernel builds the /sys/fs/selinux/initial_contexts entries using the
 *         contents of the kernel's security/selinux/include/initial_sid_to_string.h
 *         file (see kernel source security/selinux/selinuxfs.c and ss/services.c).
 *         The 'initial_sid_to_string.h' file can be generated by the Reference
 *         Policy source build script policy/flask/flask.py as it builds userspace
 *         and kernel headers based on policy (however most of the headers it
 *         generates are not required by newer kernels or SELinux userspace services).
 *
 * Note 2: There is a ToDo for "Dynamic discovery of initial SIDs" at:
 *            https://github.com/SELinuxProject/selinux/wiki/Kernel-Todo
*/
static const char *const linux_sidnames[] = {
	/* I've made them print neat & tidy, tidy & neat !!!*/
        "null",
	"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        "
};

static const char *const xen_sidnames[] = {
        "null",
	"xen      ",
	"dom0     ",
	"domio    ",
	"domxen   ",
	"unlabeled",
	"security ",
	"ioport   ",
	"iomem    ",
	"irq      ",
	"device   "
};

/* This is reworked from libsepol/src/mls.c mls_compute_context_len() to print the MLS components.
 * Best seen using MLS policy e.g. /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;
	bool have_names = false;

	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 and check if first entry has a name present in policy,
	 * if so all entries would be named. However, currently these are not
	 * present in a binary policy)
	 */
	for (cur = policydb.ocontexts[OCON_ISID]; cur != NULL; cur = cur->next) {
		if (entry == 0 && cur->u.name)
			have_names = true;
		entry++;
	}

	printf("\nThere are %d initial sids in this %s policy.\n", entry, policydb.target_platform ? "Xen" : "SELinux");
	printf("The ISID \"Name\" has been extracted from %s.\n\n",
			    have_names ? "the policy" : "an internal list that may be incorrect");

	printf("SID          Name             Context\n");
	for (cur = policydb.ocontexts[OCON_ISID], entry = 0; cur != NULL; cur = cur->next) {
		printf("0x%08x   %s  %s:%s:%s",
		    cur->sid[0],
		    /* Initial SID names are not in policy but check just in case, else use the list for the platform */
		    cur->u.name ? cur->u.name : policydb.target_platform ? xen_sidnames[cur->sid[0]] : linux_sidnames[cur->sid[0]],
		    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");
	}

	exit(0);
}
_______________________________________________
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.

Reply via email to