18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * mdp - make dummy policy
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * When pointed at a kernel tree, builds a dummy policy for that kernel
78c2ecf20Sopenharmony_ci * with exactly one type with full rights to itself.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Copyright (C) IBM Corporation, 2006
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * Authors: Serge E. Hallyn <serue@us.ibm.com>
128c2ecf20Sopenharmony_ci */
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/* NOTE: we really do want to use the kernel headers here */
168c2ecf20Sopenharmony_ci#define __EXPORTED_HEADERS__
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include <stdio.h>
198c2ecf20Sopenharmony_ci#include <stdlib.h>
208c2ecf20Sopenharmony_ci#include <unistd.h>
218c2ecf20Sopenharmony_ci#include <string.h>
228c2ecf20Sopenharmony_ci#include <linux/kconfig.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cistatic void usage(char *name)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	printf("usage: %s [-m] policy_file context_file\n", name);
278c2ecf20Sopenharmony_ci	exit(1);
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/* Class/perm mapping support */
318c2ecf20Sopenharmony_cistruct security_class_mapping {
328c2ecf20Sopenharmony_ci	const char *name;
338c2ecf20Sopenharmony_ci	const char *perms[sizeof(unsigned) * 8 + 1];
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#include "classmap.h"
378c2ecf20Sopenharmony_ci#include "initial_sid_to_string.h"
388c2ecf20Sopenharmony_ci#include "policycap_names.h"
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ciint main(int argc, char *argv[])
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	int i, j, mls = 0;
458c2ecf20Sopenharmony_ci	int initial_sid_to_string_len;
468c2ecf20Sopenharmony_ci	char **arg, *polout, *ctxout;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	FILE *fout;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	if (argc < 3)
518c2ecf20Sopenharmony_ci		usage(argv[0]);
528c2ecf20Sopenharmony_ci	arg = argv+1;
538c2ecf20Sopenharmony_ci	if (argc==4 && strcmp(argv[1], "-m") == 0) {
548c2ecf20Sopenharmony_ci		mls = 1;
558c2ecf20Sopenharmony_ci		arg++;
568c2ecf20Sopenharmony_ci	}
578c2ecf20Sopenharmony_ci	polout = *arg++;
588c2ecf20Sopenharmony_ci	ctxout = *arg;
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	fout = fopen(polout, "w");
618c2ecf20Sopenharmony_ci	if (!fout) {
628c2ecf20Sopenharmony_ci		printf("Could not open %s for writing\n", polout);
638c2ecf20Sopenharmony_ci		usage(argv[0]);
648c2ecf20Sopenharmony_ci	}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	/* print out the classes */
678c2ecf20Sopenharmony_ci	for (i = 0; secclass_map[i].name; i++)
688c2ecf20Sopenharmony_ci		fprintf(fout, "class %s\n", secclass_map[i].name);
698c2ecf20Sopenharmony_ci	fprintf(fout, "\n");
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
728c2ecf20Sopenharmony_ci	/* print out the sids */
738c2ecf20Sopenharmony_ci	for (i = 1; i < initial_sid_to_string_len; i++) {
748c2ecf20Sopenharmony_ci		const char *name = initial_sid_to_string[i];
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci		if (name)
778c2ecf20Sopenharmony_ci			fprintf(fout, "sid %s\n", name);
788c2ecf20Sopenharmony_ci		else
798c2ecf20Sopenharmony_ci			fprintf(fout, "sid unused%d\n", i);
808c2ecf20Sopenharmony_ci	}
818c2ecf20Sopenharmony_ci	fprintf(fout, "\n");
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	/* print out the class permissions */
848c2ecf20Sopenharmony_ci	for (i = 0; secclass_map[i].name; i++) {
858c2ecf20Sopenharmony_ci		struct security_class_mapping *map = &secclass_map[i];
868c2ecf20Sopenharmony_ci		fprintf(fout, "class %s\n", map->name);
878c2ecf20Sopenharmony_ci		fprintf(fout, "{\n");
888c2ecf20Sopenharmony_ci		for (j = 0; map->perms[j]; j++)
898c2ecf20Sopenharmony_ci			fprintf(fout, "\t%s\n", map->perms[j]);
908c2ecf20Sopenharmony_ci		fprintf(fout, "}\n\n");
918c2ecf20Sopenharmony_ci	}
928c2ecf20Sopenharmony_ci	fprintf(fout, "\n");
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/* print out mls declarations and constraints */
958c2ecf20Sopenharmony_ci	if (mls) {
968c2ecf20Sopenharmony_ci		fprintf(fout, "sensitivity s0;\n");
978c2ecf20Sopenharmony_ci		fprintf(fout, "sensitivity s1;\n");
988c2ecf20Sopenharmony_ci		fprintf(fout, "dominance { s0 s1 }\n");
998c2ecf20Sopenharmony_ci		fprintf(fout, "category c0;\n");
1008c2ecf20Sopenharmony_ci		fprintf(fout, "category c1;\n");
1018c2ecf20Sopenharmony_ci		fprintf(fout, "level s0:c0.c1;\n");
1028c2ecf20Sopenharmony_ci		fprintf(fout, "level s1:c0.c1;\n");
1038c2ecf20Sopenharmony_ci#define SYSTEMLOW "s0"
1048c2ecf20Sopenharmony_ci#define SYSTEMHIGH "s1:c0.c1"
1058c2ecf20Sopenharmony_ci		for (i = 0; secclass_map[i].name; i++) {
1068c2ecf20Sopenharmony_ci			struct security_class_mapping *map = &secclass_map[i];
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci			fprintf(fout, "mlsconstrain %s {\n", map->name);
1098c2ecf20Sopenharmony_ci			for (j = 0; map->perms[j]; j++)
1108c2ecf20Sopenharmony_ci				fprintf(fout, "\t%s\n", map->perms[j]);
1118c2ecf20Sopenharmony_ci			/*
1128c2ecf20Sopenharmony_ci			 * This requires all subjects and objects to be
1138c2ecf20Sopenharmony_ci			 * single-level (l2 eq h2), and that the subject
1148c2ecf20Sopenharmony_ci			 * level dominate the object level (h1 dom h2)
1158c2ecf20Sopenharmony_ci			 * in order to have any permissions to it.
1168c2ecf20Sopenharmony_ci			 */
1178c2ecf20Sopenharmony_ci			fprintf(fout, "} (l2 eq h2 and h1 dom h2);\n\n");
1188c2ecf20Sopenharmony_ci		}
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	/* enable all policy capabilities */
1228c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++)
1238c2ecf20Sopenharmony_ci		fprintf(fout, "policycap %s;\n", selinux_policycap_names[i]);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	/* types, roles, and allows */
1268c2ecf20Sopenharmony_ci	fprintf(fout, "type base_t;\n");
1278c2ecf20Sopenharmony_ci	fprintf(fout, "role base_r;\n");
1288c2ecf20Sopenharmony_ci	fprintf(fout, "role base_r types { base_t };\n");
1298c2ecf20Sopenharmony_ci	for (i = 0; secclass_map[i].name; i++)
1308c2ecf20Sopenharmony_ci		fprintf(fout, "allow base_t base_t:%s *;\n",
1318c2ecf20Sopenharmony_ci			secclass_map[i].name);
1328c2ecf20Sopenharmony_ci	fprintf(fout, "user user_u roles { base_r }");
1338c2ecf20Sopenharmony_ci	if (mls)
1348c2ecf20Sopenharmony_ci		fprintf(fout, " level %s range %s - %s", SYSTEMLOW,
1358c2ecf20Sopenharmony_ci			SYSTEMLOW, SYSTEMHIGH);
1368c2ecf20Sopenharmony_ci	fprintf(fout, ";\n");
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci#define SUBJUSERROLETYPE "user_u:base_r:base_t"
1398c2ecf20Sopenharmony_ci#define OBJUSERROLETYPE "user_u:object_r:base_t"
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	/* default sids */
1428c2ecf20Sopenharmony_ci	for (i = 1; i < initial_sid_to_string_len; i++) {
1438c2ecf20Sopenharmony_ci		const char *name = initial_sid_to_string[i];
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci		if (name)
1468c2ecf20Sopenharmony_ci			fprintf(fout, "sid %s ", name);
1478c2ecf20Sopenharmony_ci		else
1488c2ecf20Sopenharmony_ci			fprintf(fout, "sid unused%d\n", i);
1498c2ecf20Sopenharmony_ci		fprintf(fout, SUBJUSERROLETYPE "%s\n",
1508c2ecf20Sopenharmony_ci			mls ? ":" SYSTEMLOW : "");
1518c2ecf20Sopenharmony_ci	}
1528c2ecf20Sopenharmony_ci	fprintf(fout, "\n");
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci#define FS_USE(behavior, fstype)			    \
1558c2ecf20Sopenharmony_ci	fprintf(fout, "fs_use_%s %s " OBJUSERROLETYPE "%s;\n", \
1568c2ecf20Sopenharmony_ci		behavior, fstype, mls ? ":" SYSTEMLOW : "")
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	/*
1598c2ecf20Sopenharmony_ci	 * Filesystems whose inode labels can be fetched via getxattr.
1608c2ecf20Sopenharmony_ci	 */
1618c2ecf20Sopenharmony_ci#ifdef CONFIG_EXT2_FS_SECURITY
1628c2ecf20Sopenharmony_ci	FS_USE("xattr", "ext2");
1638c2ecf20Sopenharmony_ci#endif
1648c2ecf20Sopenharmony_ci#ifdef CONFIG_EXT4_FS_SECURITY
1658c2ecf20Sopenharmony_ci#ifdef CONFIG_EXT4_USE_FOR_EXT2
1668c2ecf20Sopenharmony_ci	FS_USE("xattr", "ext2");
1678c2ecf20Sopenharmony_ci#endif
1688c2ecf20Sopenharmony_ci	FS_USE("xattr", "ext3");
1698c2ecf20Sopenharmony_ci	FS_USE("xattr", "ext4");
1708c2ecf20Sopenharmony_ci#endif
1718c2ecf20Sopenharmony_ci#ifdef CONFIG_JFS_SECURITY
1728c2ecf20Sopenharmony_ci	FS_USE("xattr", "jfs");
1738c2ecf20Sopenharmony_ci#endif
1748c2ecf20Sopenharmony_ci#ifdef CONFIG_REISERFS_FS_SECURITY
1758c2ecf20Sopenharmony_ci	FS_USE("xattr", "reiserfs");
1768c2ecf20Sopenharmony_ci#endif
1778c2ecf20Sopenharmony_ci#ifdef CONFIG_JFFS2_FS_SECURITY
1788c2ecf20Sopenharmony_ci	FS_USE("xattr", "jffs2");
1798c2ecf20Sopenharmony_ci#endif
1808c2ecf20Sopenharmony_ci#ifdef CONFIG_XFS_FS
1818c2ecf20Sopenharmony_ci	FS_USE("xattr", "xfs");
1828c2ecf20Sopenharmony_ci#endif
1838c2ecf20Sopenharmony_ci#ifdef CONFIG_GFS2_FS
1848c2ecf20Sopenharmony_ci	FS_USE("xattr", "gfs2");
1858c2ecf20Sopenharmony_ci#endif
1868c2ecf20Sopenharmony_ci#ifdef CONFIG_BTRFS_FS
1878c2ecf20Sopenharmony_ci	FS_USE("xattr", "btrfs");
1888c2ecf20Sopenharmony_ci#endif
1898c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_SECURITY
1908c2ecf20Sopenharmony_ci	FS_USE("xattr", "f2fs");
1918c2ecf20Sopenharmony_ci#endif
1928c2ecf20Sopenharmony_ci#ifdef CONFIG_OCFS2_FS
1938c2ecf20Sopenharmony_ci	FS_USE("xattr", "ocsfs2");
1948c2ecf20Sopenharmony_ci#endif
1958c2ecf20Sopenharmony_ci#ifdef CONFIG_OVERLAY_FS
1968c2ecf20Sopenharmony_ci	FS_USE("xattr", "overlay");
1978c2ecf20Sopenharmony_ci#endif
1988c2ecf20Sopenharmony_ci#ifdef CONFIG_SQUASHFS_XATTR
1998c2ecf20Sopenharmony_ci	FS_USE("xattr", "squashfs");
2008c2ecf20Sopenharmony_ci#endif
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	/*
2038c2ecf20Sopenharmony_ci	 * Filesystems whose inodes are labeled from allocating task.
2048c2ecf20Sopenharmony_ci	 */
2058c2ecf20Sopenharmony_ci	FS_USE("task", "pipefs");
2068c2ecf20Sopenharmony_ci	FS_USE("task", "sockfs");
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	/*
2098c2ecf20Sopenharmony_ci	 * Filesystems whose inode labels are computed from both
2108c2ecf20Sopenharmony_ci	 * the allocating task and the superblock label.
2118c2ecf20Sopenharmony_ci	 */
2128c2ecf20Sopenharmony_ci#ifdef CONFIG_UNIX98_PTYS
2138c2ecf20Sopenharmony_ci	FS_USE("trans", "devpts");
2148c2ecf20Sopenharmony_ci#endif
2158c2ecf20Sopenharmony_ci#ifdef CONFIG_HUGETLBFS
2168c2ecf20Sopenharmony_ci	FS_USE("trans", "hugetlbfs");
2178c2ecf20Sopenharmony_ci#endif
2188c2ecf20Sopenharmony_ci#ifdef CONFIG_TMPFS
2198c2ecf20Sopenharmony_ci	FS_USE("trans", "tmpfs");
2208c2ecf20Sopenharmony_ci#endif
2218c2ecf20Sopenharmony_ci#ifdef CONFIG_DEVTMPFS
2228c2ecf20Sopenharmony_ci	FS_USE("trans", "devtmpfs");
2238c2ecf20Sopenharmony_ci#endif
2248c2ecf20Sopenharmony_ci#ifdef CONFIG_POSIX_MQUEUE
2258c2ecf20Sopenharmony_ci	FS_USE("trans", "mqueue");
2268c2ecf20Sopenharmony_ci#endif
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci#define GENFSCON(fstype, prefix)			     \
2298c2ecf20Sopenharmony_ci	fprintf(fout, "genfscon %s %s " OBJUSERROLETYPE "%s\n", \
2308c2ecf20Sopenharmony_ci		fstype, prefix, mls ? ":" SYSTEMLOW : "")
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	/*
2338c2ecf20Sopenharmony_ci	 * Filesystems whose inodes are labeled from path prefix match
2348c2ecf20Sopenharmony_ci	 * relative to the filesystem root.  Depending on the filesystem,
2358c2ecf20Sopenharmony_ci	 * only a single label for all inodes may be supported.  Here
2368c2ecf20Sopenharmony_ci	 * we list the filesystem types for which per-file labeling is
2378c2ecf20Sopenharmony_ci	 * supported using genfscon; any other filesystem type can also
2388c2ecf20Sopenharmony_ci	 * be added by only with a single entry for all of its inodes.
2398c2ecf20Sopenharmony_ci	 */
2408c2ecf20Sopenharmony_ci#ifdef CONFIG_PROC_FS
2418c2ecf20Sopenharmony_ci	GENFSCON("proc", "/");
2428c2ecf20Sopenharmony_ci#endif
2438c2ecf20Sopenharmony_ci#ifdef CONFIG_SECURITY_SELINUX
2448c2ecf20Sopenharmony_ci	GENFSCON("selinuxfs", "/");
2458c2ecf20Sopenharmony_ci#endif
2468c2ecf20Sopenharmony_ci#ifdef CONFIG_SYSFS
2478c2ecf20Sopenharmony_ci	GENFSCON("sysfs", "/");
2488c2ecf20Sopenharmony_ci#endif
2498c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
2508c2ecf20Sopenharmony_ci	GENFSCON("debugfs", "/");
2518c2ecf20Sopenharmony_ci#endif
2528c2ecf20Sopenharmony_ci#ifdef CONFIG_TRACING
2538c2ecf20Sopenharmony_ci	GENFSCON("tracefs", "/");
2548c2ecf20Sopenharmony_ci#endif
2558c2ecf20Sopenharmony_ci#ifdef CONFIG_PSTORE
2568c2ecf20Sopenharmony_ci	GENFSCON("pstore", "/");
2578c2ecf20Sopenharmony_ci#endif
2588c2ecf20Sopenharmony_ci	GENFSCON("cgroup", "/");
2598c2ecf20Sopenharmony_ci	GENFSCON("cgroup2", "/");
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	fclose(fout);
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	fout = fopen(ctxout, "w");
2648c2ecf20Sopenharmony_ci	if (!fout) {
2658c2ecf20Sopenharmony_ci		printf("Wrote policy, but cannot open %s for writing\n", ctxout);
2668c2ecf20Sopenharmony_ci		usage(argv[0]);
2678c2ecf20Sopenharmony_ci	}
2688c2ecf20Sopenharmony_ci	fprintf(fout, "/ " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : "");
2698c2ecf20Sopenharmony_ci	fprintf(fout, "/.* " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : "");
2708c2ecf20Sopenharmony_ci	fclose(fout);
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	return 0;
2738c2ecf20Sopenharmony_ci}
274