162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * mdp - make dummy policy 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * When pointed at a kernel tree, builds a dummy policy for that kernel 762306a36Sopenharmony_ci * with exactly one type with full rights to itself. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Copyright (C) IBM Corporation, 2006 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Authors: Serge E. Hallyn <serue@us.ibm.com> 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* NOTE: we really do want to use the kernel headers here */ 1662306a36Sopenharmony_ci#define __EXPORTED_HEADERS__ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <stdio.h> 1962306a36Sopenharmony_ci#include <stdlib.h> 2062306a36Sopenharmony_ci#include <unistd.h> 2162306a36Sopenharmony_ci#include <string.h> 2262306a36Sopenharmony_ci#include <linux/kconfig.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic void usage(char *name) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci printf("usage: %s [-m] policy_file context_file\n", name); 2762306a36Sopenharmony_ci exit(1); 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* Class/perm mapping support */ 3162306a36Sopenharmony_cistruct security_class_mapping { 3262306a36Sopenharmony_ci const char *name; 3362306a36Sopenharmony_ci const char *perms[sizeof(unsigned) * 8 + 1]; 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#include "classmap.h" 3762306a36Sopenharmony_ci#include "initial_sid_to_string.h" 3862306a36Sopenharmony_ci#include "policycap_names.h" 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ciint main(int argc, char *argv[]) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci int i, j, mls = 0; 4562306a36Sopenharmony_ci int initial_sid_to_string_len; 4662306a36Sopenharmony_ci char **arg, *polout, *ctxout; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci FILE *fout; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (argc < 3) 5162306a36Sopenharmony_ci usage(argv[0]); 5262306a36Sopenharmony_ci arg = argv+1; 5362306a36Sopenharmony_ci if (argc==4 && strcmp(argv[1], "-m") == 0) { 5462306a36Sopenharmony_ci mls = 1; 5562306a36Sopenharmony_ci arg++; 5662306a36Sopenharmony_ci } 5762306a36Sopenharmony_ci polout = *arg++; 5862306a36Sopenharmony_ci ctxout = *arg; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci fout = fopen(polout, "w"); 6162306a36Sopenharmony_ci if (!fout) { 6262306a36Sopenharmony_ci printf("Could not open %s for writing\n", polout); 6362306a36Sopenharmony_ci usage(argv[0]); 6462306a36Sopenharmony_ci } 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci /* print out the classes */ 6762306a36Sopenharmony_ci for (i = 0; secclass_map[i].name; i++) 6862306a36Sopenharmony_ci fprintf(fout, "class %s\n", secclass_map[i].name); 6962306a36Sopenharmony_ci fprintf(fout, "\n"); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); 7262306a36Sopenharmony_ci /* print out the sids */ 7362306a36Sopenharmony_ci for (i = 1; i < initial_sid_to_string_len; i++) { 7462306a36Sopenharmony_ci const char *name = initial_sid_to_string[i]; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci if (name) 7762306a36Sopenharmony_ci fprintf(fout, "sid %s\n", name); 7862306a36Sopenharmony_ci else 7962306a36Sopenharmony_ci fprintf(fout, "sid unused%d\n", i); 8062306a36Sopenharmony_ci } 8162306a36Sopenharmony_ci fprintf(fout, "\n"); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci /* print out the class permissions */ 8462306a36Sopenharmony_ci for (i = 0; secclass_map[i].name; i++) { 8562306a36Sopenharmony_ci const struct security_class_mapping *map = &secclass_map[i]; 8662306a36Sopenharmony_ci fprintf(fout, "class %s\n", map->name); 8762306a36Sopenharmony_ci fprintf(fout, "{\n"); 8862306a36Sopenharmony_ci for (j = 0; map->perms[j]; j++) 8962306a36Sopenharmony_ci fprintf(fout, "\t%s\n", map->perms[j]); 9062306a36Sopenharmony_ci fprintf(fout, "}\n\n"); 9162306a36Sopenharmony_ci } 9262306a36Sopenharmony_ci fprintf(fout, "\n"); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci /* print out mls declarations and constraints */ 9562306a36Sopenharmony_ci if (mls) { 9662306a36Sopenharmony_ci fprintf(fout, "sensitivity s0;\n"); 9762306a36Sopenharmony_ci fprintf(fout, "sensitivity s1;\n"); 9862306a36Sopenharmony_ci fprintf(fout, "dominance { s0 s1 }\n"); 9962306a36Sopenharmony_ci fprintf(fout, "category c0;\n"); 10062306a36Sopenharmony_ci fprintf(fout, "category c1;\n"); 10162306a36Sopenharmony_ci fprintf(fout, "level s0:c0.c1;\n"); 10262306a36Sopenharmony_ci fprintf(fout, "level s1:c0.c1;\n"); 10362306a36Sopenharmony_ci#define SYSTEMLOW "s0" 10462306a36Sopenharmony_ci#define SYSTEMHIGH "s1:c0.c1" 10562306a36Sopenharmony_ci for (i = 0; secclass_map[i].name; i++) { 10662306a36Sopenharmony_ci const struct security_class_mapping *map = &secclass_map[i]; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci fprintf(fout, "mlsconstrain %s {\n", map->name); 10962306a36Sopenharmony_ci for (j = 0; map->perms[j]; j++) 11062306a36Sopenharmony_ci fprintf(fout, "\t%s\n", map->perms[j]); 11162306a36Sopenharmony_ci /* 11262306a36Sopenharmony_ci * This requires all subjects and objects to be 11362306a36Sopenharmony_ci * single-level (l2 eq h2), and that the subject 11462306a36Sopenharmony_ci * level dominate the object level (h1 dom h2) 11562306a36Sopenharmony_ci * in order to have any permissions to it. 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_ci fprintf(fout, "} (l2 eq h2 and h1 dom h2);\n\n"); 11862306a36Sopenharmony_ci } 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* enable all policy capabilities */ 12262306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++) 12362306a36Sopenharmony_ci fprintf(fout, "policycap %s;\n", selinux_policycap_names[i]); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci /* types, roles, and allows */ 12662306a36Sopenharmony_ci fprintf(fout, "type base_t;\n"); 12762306a36Sopenharmony_ci fprintf(fout, "role base_r;\n"); 12862306a36Sopenharmony_ci fprintf(fout, "role base_r types { base_t };\n"); 12962306a36Sopenharmony_ci for (i = 0; secclass_map[i].name; i++) 13062306a36Sopenharmony_ci fprintf(fout, "allow base_t base_t:%s *;\n", 13162306a36Sopenharmony_ci secclass_map[i].name); 13262306a36Sopenharmony_ci fprintf(fout, "user user_u roles { base_r }"); 13362306a36Sopenharmony_ci if (mls) 13462306a36Sopenharmony_ci fprintf(fout, " level %s range %s - %s", SYSTEMLOW, 13562306a36Sopenharmony_ci SYSTEMLOW, SYSTEMHIGH); 13662306a36Sopenharmony_ci fprintf(fout, ";\n"); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci#define SUBJUSERROLETYPE "user_u:base_r:base_t" 13962306a36Sopenharmony_ci#define OBJUSERROLETYPE "user_u:object_r:base_t" 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci /* default sids */ 14262306a36Sopenharmony_ci for (i = 1; i < initial_sid_to_string_len; i++) { 14362306a36Sopenharmony_ci const char *name = initial_sid_to_string[i]; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci if (name) 14662306a36Sopenharmony_ci fprintf(fout, "sid %s ", name); 14762306a36Sopenharmony_ci else 14862306a36Sopenharmony_ci fprintf(fout, "sid unused%d\n", i); 14962306a36Sopenharmony_ci fprintf(fout, SUBJUSERROLETYPE "%s\n", 15062306a36Sopenharmony_ci mls ? ":" SYSTEMLOW : ""); 15162306a36Sopenharmony_ci } 15262306a36Sopenharmony_ci fprintf(fout, "\n"); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci#define FS_USE(behavior, fstype) \ 15562306a36Sopenharmony_ci fprintf(fout, "fs_use_%s %s " OBJUSERROLETYPE "%s;\n", \ 15662306a36Sopenharmony_ci behavior, fstype, mls ? ":" SYSTEMLOW : "") 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* 15962306a36Sopenharmony_ci * Filesystems whose inode labels can be fetched via getxattr. 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ci#ifdef CONFIG_EXT2_FS_SECURITY 16262306a36Sopenharmony_ci FS_USE("xattr", "ext2"); 16362306a36Sopenharmony_ci#endif 16462306a36Sopenharmony_ci#ifdef CONFIG_EXT4_FS_SECURITY 16562306a36Sopenharmony_ci#ifdef CONFIG_EXT4_USE_FOR_EXT2 16662306a36Sopenharmony_ci FS_USE("xattr", "ext2"); 16762306a36Sopenharmony_ci#endif 16862306a36Sopenharmony_ci FS_USE("xattr", "ext3"); 16962306a36Sopenharmony_ci FS_USE("xattr", "ext4"); 17062306a36Sopenharmony_ci#endif 17162306a36Sopenharmony_ci#ifdef CONFIG_JFS_SECURITY 17262306a36Sopenharmony_ci FS_USE("xattr", "jfs"); 17362306a36Sopenharmony_ci#endif 17462306a36Sopenharmony_ci#ifdef CONFIG_REISERFS_FS_SECURITY 17562306a36Sopenharmony_ci FS_USE("xattr", "reiserfs"); 17662306a36Sopenharmony_ci#endif 17762306a36Sopenharmony_ci#ifdef CONFIG_JFFS2_FS_SECURITY 17862306a36Sopenharmony_ci FS_USE("xattr", "jffs2"); 17962306a36Sopenharmony_ci#endif 18062306a36Sopenharmony_ci#ifdef CONFIG_XFS_FS 18162306a36Sopenharmony_ci FS_USE("xattr", "xfs"); 18262306a36Sopenharmony_ci#endif 18362306a36Sopenharmony_ci#ifdef CONFIG_GFS2_FS 18462306a36Sopenharmony_ci FS_USE("xattr", "gfs2"); 18562306a36Sopenharmony_ci#endif 18662306a36Sopenharmony_ci#ifdef CONFIG_BTRFS_FS 18762306a36Sopenharmony_ci FS_USE("xattr", "btrfs"); 18862306a36Sopenharmony_ci#endif 18962306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_SECURITY 19062306a36Sopenharmony_ci FS_USE("xattr", "f2fs"); 19162306a36Sopenharmony_ci#endif 19262306a36Sopenharmony_ci#ifdef CONFIG_OCFS2_FS 19362306a36Sopenharmony_ci FS_USE("xattr", "ocsfs2"); 19462306a36Sopenharmony_ci#endif 19562306a36Sopenharmony_ci#ifdef CONFIG_OVERLAY_FS 19662306a36Sopenharmony_ci FS_USE("xattr", "overlay"); 19762306a36Sopenharmony_ci#endif 19862306a36Sopenharmony_ci#ifdef CONFIG_SQUASHFS_XATTR 19962306a36Sopenharmony_ci FS_USE("xattr", "squashfs"); 20062306a36Sopenharmony_ci#endif 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* 20362306a36Sopenharmony_ci * Filesystems whose inodes are labeled from allocating task. 20462306a36Sopenharmony_ci */ 20562306a36Sopenharmony_ci FS_USE("task", "pipefs"); 20662306a36Sopenharmony_ci FS_USE("task", "sockfs"); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci /* 20962306a36Sopenharmony_ci * Filesystems whose inode labels are computed from both 21062306a36Sopenharmony_ci * the allocating task and the superblock label. 21162306a36Sopenharmony_ci */ 21262306a36Sopenharmony_ci#ifdef CONFIG_UNIX98_PTYS 21362306a36Sopenharmony_ci FS_USE("trans", "devpts"); 21462306a36Sopenharmony_ci#endif 21562306a36Sopenharmony_ci#ifdef CONFIG_HUGETLBFS 21662306a36Sopenharmony_ci FS_USE("trans", "hugetlbfs"); 21762306a36Sopenharmony_ci#endif 21862306a36Sopenharmony_ci#ifdef CONFIG_TMPFS 21962306a36Sopenharmony_ci FS_USE("trans", "tmpfs"); 22062306a36Sopenharmony_ci#endif 22162306a36Sopenharmony_ci#ifdef CONFIG_DEVTMPFS 22262306a36Sopenharmony_ci FS_USE("trans", "devtmpfs"); 22362306a36Sopenharmony_ci#endif 22462306a36Sopenharmony_ci#ifdef CONFIG_POSIX_MQUEUE 22562306a36Sopenharmony_ci FS_USE("trans", "mqueue"); 22662306a36Sopenharmony_ci#endif 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci#define GENFSCON(fstype, prefix) \ 22962306a36Sopenharmony_ci fprintf(fout, "genfscon %s %s " OBJUSERROLETYPE "%s\n", \ 23062306a36Sopenharmony_ci fstype, prefix, mls ? ":" SYSTEMLOW : "") 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* 23362306a36Sopenharmony_ci * Filesystems whose inodes are labeled from path prefix match 23462306a36Sopenharmony_ci * relative to the filesystem root. Depending on the filesystem, 23562306a36Sopenharmony_ci * only a single label for all inodes may be supported. Here 23662306a36Sopenharmony_ci * we list the filesystem types for which per-file labeling is 23762306a36Sopenharmony_ci * supported using genfscon; any other filesystem type can also 23862306a36Sopenharmony_ci * be added by only with a single entry for all of its inodes. 23962306a36Sopenharmony_ci */ 24062306a36Sopenharmony_ci#ifdef CONFIG_PROC_FS 24162306a36Sopenharmony_ci GENFSCON("proc", "/"); 24262306a36Sopenharmony_ci#endif 24362306a36Sopenharmony_ci#ifdef CONFIG_SECURITY_SELINUX 24462306a36Sopenharmony_ci GENFSCON("selinuxfs", "/"); 24562306a36Sopenharmony_ci#endif 24662306a36Sopenharmony_ci#ifdef CONFIG_SYSFS 24762306a36Sopenharmony_ci GENFSCON("sysfs", "/"); 24862306a36Sopenharmony_ci#endif 24962306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 25062306a36Sopenharmony_ci GENFSCON("debugfs", "/"); 25162306a36Sopenharmony_ci#endif 25262306a36Sopenharmony_ci#ifdef CONFIG_TRACING 25362306a36Sopenharmony_ci GENFSCON("tracefs", "/"); 25462306a36Sopenharmony_ci#endif 25562306a36Sopenharmony_ci#ifdef CONFIG_PSTORE 25662306a36Sopenharmony_ci GENFSCON("pstore", "/"); 25762306a36Sopenharmony_ci#endif 25862306a36Sopenharmony_ci GENFSCON("cgroup", "/"); 25962306a36Sopenharmony_ci GENFSCON("cgroup2", "/"); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci fclose(fout); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci fout = fopen(ctxout, "w"); 26462306a36Sopenharmony_ci if (!fout) { 26562306a36Sopenharmony_ci printf("Wrote policy, but cannot open %s for writing\n", ctxout); 26662306a36Sopenharmony_ci usage(argv[0]); 26762306a36Sopenharmony_ci } 26862306a36Sopenharmony_ci fprintf(fout, "/ " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : ""); 26962306a36Sopenharmony_ci fprintf(fout, "/.* " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : ""); 27062306a36Sopenharmony_ci fclose(fout); 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci return 0; 27362306a36Sopenharmony_ci} 274