1f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <unistd.h>
2f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <fcntl.h>
3f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <string.h>
4f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdlib.h>
5f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <errno.h>
6f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <ctype.h>
7f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdio.h>
8f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <dlfcn.h>
9cc3d76d1b717805740126aec7e0343f5a240cfbeStephen Smalley
10cc3d76d1b717805740126aec7e0343f5a240cfbeStephen Smalley#ifdef DARWIN
11cc3d76d1b717805740126aec7e0343f5a240cfbeStephen Smalley#include <sys/param.h>
12cc3d76d1b717805740126aec7e0343f5a240cfbeStephen Smalley#include <sys/mount.h>
13cc3d76d1b717805740126aec7e0343f5a240cfbeStephen Smalley#else
14f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <sys/vfs.h>
15cc3d76d1b717805740126aec7e0343f5a240cfbeStephen Smalley#endif
16cc3d76d1b717805740126aec7e0343f5a240cfbeStephen Smalley
17f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdint.h>
18f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <limits.h>
19f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
20f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "dso.h"
21f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "policy.h"
22f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "selinux_internal.h"
23f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
24f074036424618c130dacb3464465a8b40bffef5Stephen Smalleychar *selinux_mnt = NULL;
25f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyint selinux_page_size = 0;
26f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
27f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic void init_selinuxmnt(void)
28f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{
29f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	char buf[BUFSIZ], *p;
30f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	FILE *fp=NULL;
31f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	struct statfs sfbuf;
32f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	int rc;
33f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	char *bufp;
34f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	int exists = 0;
35f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
36f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (selinux_mnt)
37f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		return;
38f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
39f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	/* We check to see if the preferred mount point for selinux file
40f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	 * system has a selinuxfs. */
41f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	do {
42f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		rc = statfs(SELINUXMNT, &sfbuf);
43f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	} while (rc < 0 && errno == EINTR);
44f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (rc == 0) {
45f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) {
46f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			selinux_mnt = strdup(SELINUXMNT);
47f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			return;
48f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		}
49f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	}
50f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
51f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	/* Drop back to detecting it the long way. */
52f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	fp = fopen("/proc/filesystems", "r");
53f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (!fp)
54f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		return;
55f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
56f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	while ((bufp = fgets(buf, sizeof buf - 1, fp)) != NULL) {
57f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		if (strstr(buf, "selinuxfs")) {
58f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			exists = 1;
59f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			break;
60f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		}
61f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	}
62f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
63f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (!exists)
64f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		goto out;
65f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
66f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	fclose(fp);
67f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
68f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	/* At this point, the usual spot doesn't have an selinuxfs so
69f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	 * we look around for it */
70f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	fp = fopen("/proc/mounts", "r");
71f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (!fp)
72f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		goto out;
73f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
74f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	while ((bufp = fgets(buf, sizeof buf - 1, fp)) != NULL) {
75f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		char *tmp;
76f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		p = strchr(buf, ' ');
77f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		if (!p)
78f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			goto out;
79f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		p++;
80f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		tmp = strchr(p, ' ');
81f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		if (!tmp)
82f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			goto out;
83f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		if (!strncmp(tmp + 1, "selinuxfs ", 10)) {
84f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			*tmp = '\0';
85f074036424618c130dacb3464465a8b40bffef5Stephen Smalley			break;
86f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		}
87f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	}
88f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
89f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	/* If we found something, dup it */
90f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (bufp)
91f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		selinux_mnt = strdup(p);
92f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
93f074036424618c130dacb3464465a8b40bffef5Stephen Smalley      out:
94f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	if (fp)
95f074036424618c130dacb3464465a8b40bffef5Stephen Smalley		fclose(fp);
96f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	return;
97f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}
98f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
99f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyvoid fini_selinuxmnt(void)
100f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{
101f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	free(selinux_mnt);
102f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	selinux_mnt = NULL;
103f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}
104f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
105f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyvoid set_selinuxmnt(char *mnt)
106f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{
107f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	selinux_mnt = strdup(mnt);
108f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}
109f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
110f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyhidden_def(set_selinuxmnt)
111f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
112f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic void init_lib(void) __attribute__ ((constructor));
113f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic void init_lib(void)
114f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{
115f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	selinux_page_size = sysconf(_SC_PAGE_SIZE);
116f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	init_selinuxmnt();
117f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}
118f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
119f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic void fini_lib(void) __attribute__ ((destructor));
120f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic void fini_lib(void)
121f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{
122f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	fini_selinuxmnt();
123f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}
124