> On Saturday, 5 March 2016, 14:48, Richard Haines <richard_c_haines@xxxxxxxxxxxxxx> wrote:
> >
>
>
>
> 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
I've updated the example with more detail and display SID name using SID value not counter.
>
>>
>>
>> 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.
>>
>>
>
> _______________________________________________
> 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 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@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.