summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2019-02-21 16:31:47 -0500
committerPaul Moore <paul@paul-moore.com>2019-03-18 18:38:28 -0400
commite37c1877ba5b17d4251e1688449f8d43fc090802 (patch)
tree9d4af948a7cb406ddd9447e8b367afa281819fba /scripts
parent9e98c678c2d6ae3a17cb2de55d17f69dddaa231b (diff)
scripts/selinux: modernize mdp
Derived in part from a patch by Dominick Grift. The MDP example no longer works on modern systems. Fix it. While we are at it, add MLS support and enable it. NB This still does not work on systems using dbus-daemon instead of dbus-broker because dbus-daemon does not yet gracefully handle unknown classes/permissions. This appears to be a deficiency in libselinux's selinux_set_mapping() interface and underlying implementation, which was never fully updated to deal with unknown classes/permissions unlike the kernel. The same problem also occurs with XSELinux. Programs that instead use selinux_check_access() like dbus-broker should not have this problem. Changes to mdp: Add support for devtmpfs, required by modern Linux distributions. Add MLS support, with sample sensitivities, categories, and constraints. Generate fs_use and genfscon rules based on kernel configuration. Update list of filesystem types for fs_use and genfscon rules. Use object_r for object contexts. Changes to install_policy.sh: Bail immediately on any errors. Provide more helpful error messages when unable to find userspace tools. Refuse to run if SELinux is already enabled. Unconditionally move aside /etc/selinux/config and create a new one. Build policy with -U allow so that userspace object managers do not break. Build policy with MLS enabled by default. Create seusers, failsafe_context, and default_contexts for use by pam_selinux / libselinux. Create x_contexts for the SELinux X extension. Create virtual_domain_context and virtual_image_context for libvirtd. Set to permissive mode rather than enforcing to permit initial autorelabel. Update the list of filesystem types to be relabeled. Write -F to /.autorelabel to cause a forced autorelabel on reboot. Drop broken attempt to relabel the /dev mountpoint directory. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: Dominick Grift <dominick.grift@defensec.nl> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/selinux/install_policy.sh92
-rw-r--r--scripts/selinux/mdp/mdp.c165
2 files changed, 194 insertions, 63 deletions
diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh
index 0b86c47baf7d..2dccf141241d 100755
--- a/scripts/selinux/install_policy.sh
+++ b/scripts/selinux/install_policy.sh
@@ -1,30 +1,61 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3set -e
3if [ `id -u` -ne 0 ]; then 4if [ `id -u` -ne 0 ]; then
4 echo "$0: must be root to install the selinux policy" 5 echo "$0: must be root to install the selinux policy"
5 exit 1 6 exit 1
6fi 7fi
8
7SF=`which setfiles` 9SF=`which setfiles`
8if [ $? -eq 1 ]; then 10if [ $? -eq 1 ]; then
9 if [ -f /sbin/setfiles ]; then 11 echo "Could not find setfiles"
10 SF="/usr/setfiles" 12 echo "Do you have policycoreutils installed?"
11 else 13 exit 1
12 echo "no selinux tools installed: setfiles"
13 exit 1
14 fi
15fi 14fi
16 15
17cd mdp
18
19CP=`which checkpolicy` 16CP=`which checkpolicy`
17if [ $? -eq 1 ]; then
18 echo "Could not find checkpolicy"
19 echo "Do you have checkpolicy installed?"
20 exit 1
21fi
20VERS=`$CP -V | awk '{print $1}'` 22VERS=`$CP -V | awk '{print $1}'`
21 23
22./mdp policy.conf file_contexts 24ENABLED=`which selinuxenabled`
23$CP -o policy.$VERS policy.conf 25if [ $? -eq 1 ]; then
26 echo "Could not find selinuxenabled"
27 echo "Do you have libselinux-utils installed?"
28 exit 1
29fi
30
31if selinuxenabled; then
32 echo "SELinux is already enabled"
33 echo "This prevents safely relabeling all files."
34 echo "Boot with selinux=0 on the kernel command-line or"
35 echo "SELINUX=disabled in /etc/selinux/config."
36 exit 1
37fi
38
39cd mdp
40./mdp -m policy.conf file_contexts
41$CP -U allow -M -o policy.$VERS policy.conf
24 42
25mkdir -p /etc/selinux/dummy/policy 43mkdir -p /etc/selinux/dummy/policy
26mkdir -p /etc/selinux/dummy/contexts/files 44mkdir -p /etc/selinux/dummy/contexts/files
27 45
46echo "__default__:user_u:s0" > /etc/selinux/dummy/seusers
47echo "base_r:base_t:s0" > /etc/selinux/dummy/contexts/failsafe_context
48echo "base_r:base_t:s0 base_r:base_t:s0" > /etc/selinux/dummy/default_contexts
49cat > /etc/selinux/dummy/contexts/x_contexts <<EOF
50client * user_u:base_r:base_t:s0
51property * user_u:object_r:base_t:s0
52extension * user_u:object_r:base_t:s0
53selection * user_u:object_r:base_t:s0
54event * user_u:object_r:base_t:s0
55EOF
56touch /etc/selinux/dummy/contexts/virtual_domain_context
57touch /etc/selinux/dummy/contexts/virtual_image_context
58
28cp file_contexts /etc/selinux/dummy/contexts/files 59cp file_contexts /etc/selinux/dummy/contexts/files
29cp dbus_contexts /etc/selinux/dummy/contexts 60cp dbus_contexts /etc/selinux/dummy/contexts
30cp policy.$VERS /etc/selinux/dummy/policy 61cp policy.$VERS /etc/selinux/dummy/policy
@@ -33,37 +64,22 @@ FC_FILE=/etc/selinux/dummy/contexts/files/file_contexts
33if [ ! -d /etc/selinux ]; then 64if [ ! -d /etc/selinux ]; then
34 mkdir -p /etc/selinux 65 mkdir -p /etc/selinux
35fi 66fi
36if [ ! -f /etc/selinux/config ]; then 67if [ -f /etc/selinux/config ]; then
37 cat > /etc/selinux/config << EOF 68 echo "/etc/selinux/config exists, moving to /etc/selinux/config.bak."
38SELINUX=enforcing 69 mv /etc/selinux/config /etc/selinux/config.bak
70fi
71echo "Creating new /etc/selinux/config for dummy policy."
72cat > /etc/selinux/config << EOF
73SELINUX=permissive
39SELINUXTYPE=dummy 74SELINUXTYPE=dummy
40EOF 75EOF
41else
42 TYPE=`cat /etc/selinux/config | grep "^SELINUXTYPE" | tail -1 | awk -F= '{ print $2 '}`
43 if [ "eq$TYPE" != "eqdummy" ]; then
44 selinuxenabled
45 if [ $? -eq 0 ]; then
46 echo "SELinux already enabled with a non-dummy policy."
47 echo "Exiting. Please install policy by hand if that"
48 echo "is what you REALLY want."
49 exit 1
50 fi
51 mv /etc/selinux/config /etc/selinux/config.mdpbak
52 grep -v "^SELINUXTYPE" /etc/selinux/config.mdpbak >> /etc/selinux/config
53 echo "SELINUXTYPE=dummy" >> /etc/selinux/config
54 fi
55fi
56 76
57cd /etc/selinux/dummy/contexts/files 77cd /etc/selinux/dummy/contexts/files
58$SF file_contexts / 78$SF -F file_contexts /
59 79
60mounts=`cat /proc/$$/mounts | egrep "ext2|ext3|xfs|jfs|ext4|ext4dev|gfs2" | awk '{ print $2 '}` 80mounts=`cat /proc/$$/mounts | \
61$SF file_contexts $mounts 81 egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
82 awk '{ print $2 '}`
83$SF -F file_contexts $mounts
62 84
63 85echo "-F" > /.autorelabel
64dodev=`cat /proc/$$/mounts | grep "/dev "`
65if [ "eq$dodev" != "eq" ]; then
66 mount --move /dev /mnt
67 $SF file_contexts /dev
68 mount --move /mnt /dev
69fi
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
index 073fe7537f6c..edaba8e51651 100644
--- a/scripts/selinux/mdp/mdp.c
+++ b/scripts/selinux/mdp/mdp.c
@@ -33,6 +33,7 @@
33#include <unistd.h> 33#include <unistd.h>
34#include <string.h> 34#include <string.h>
35#include <sys/socket.h> 35#include <sys/socket.h>
36#include <linux/kconfig.h>
36 37
37static void usage(char *name) 38static void usage(char *name)
38{ 39{
@@ -95,10 +96,31 @@ int main(int argc, char *argv[])
95 } 96 }
96 fprintf(fout, "\n"); 97 fprintf(fout, "\n");
97 98
98 /* NOW PRINT OUT MLS STUFF */ 99 /* print out mls declarations and constraints */
99 if (mls) { 100 if (mls) {
100 printf("MLS not yet implemented\n"); 101 fprintf(fout, "sensitivity s0;\n");
101 exit(1); 102 fprintf(fout, "sensitivity s1;\n");
103 fprintf(fout, "dominance { s0 s1 }\n");
104 fprintf(fout, "category c0;\n");
105 fprintf(fout, "category c1;\n");
106 fprintf(fout, "level s0:c0.c1;\n");
107 fprintf(fout, "level s1:c0.c1;\n");
108#define SYSTEMLOW "s0"
109#define SYSTEMHIGH "s1:c0.c1"
110 for (i = 0; secclass_map[i].name; i++) {
111 struct security_class_mapping *map = &secclass_map[i];
112
113 fprintf(fout, "mlsconstrain %s {\n", map->name);
114 for (j = 0; map->perms[j]; j++)
115 fprintf(fout, "\t%s\n", map->perms[j]);
116 /*
117 * This requires all subjects and objects to be
118 * single-level (l2 eq h2), and that the subject
119 * level dominate the object level (h1 dom h2)
120 * in order to have any permissions to it.
121 */
122 fprintf(fout, "} (l2 eq h2 and h1 dom h2);\n\n");
123 }
102 } 124 }
103 125
104 /* types, roles, and allows */ 126 /* types, roles, and allows */
@@ -108,34 +130,127 @@ int main(int argc, char *argv[])
108 for (i = 0; secclass_map[i].name; i++) 130 for (i = 0; secclass_map[i].name; i++)
109 fprintf(fout, "allow base_t base_t:%s *;\n", 131 fprintf(fout, "allow base_t base_t:%s *;\n",
110 secclass_map[i].name); 132 secclass_map[i].name);
111 fprintf(fout, "user user_u roles { base_r };\n"); 133 fprintf(fout, "user user_u roles { base_r }");
112 fprintf(fout, "\n"); 134 if (mls)
135 fprintf(fout, " level %s range %s - %s", SYSTEMLOW,
136 SYSTEMLOW, SYSTEMHIGH);
137 fprintf(fout, ";\n");
138
139#define SUBJUSERROLETYPE "user_u:base_r:base_t"
140#define OBJUSERROLETYPE "user_u:object_r:base_t"
113 141
114 /* default sids */ 142 /* default sids */
115 for (i = 1; i < initial_sid_to_string_len; i++) 143 for (i = 1; i < initial_sid_to_string_len; i++)
116 fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); 144 fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n",
145 initial_sid_to_string[i], mls ? ":" SYSTEMLOW : "");
117 fprintf(fout, "\n"); 146 fprintf(fout, "\n");
118 147
119 fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); 148#define FS_USE(behavior, fstype) \
120 fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); 149 fprintf(fout, "fs_use_%s %s " OBJUSERROLETYPE "%s;\n", \
121 fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n"); 150 behavior, fstype, mls ? ":" SYSTEMLOW : "")
122 fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); 151
123 fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); 152 /*
124 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); 153 * Filesystems whose inode labels can be fetched via getxattr.
125 fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n"); 154 */
126 fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n"); 155#ifdef CONFIG_EXT2_FS_SECURITY
156 FS_USE("xattr", "ext2");
157#endif
158#ifdef CONFIG_EXT4_FS_SECURITY
159#ifdef CONFIG_EXT4_USE_FOR_EXT2
160 FS_USE("xattr", "ext2");
161#endif
162 FS_USE("xattr", "ext3");
163 FS_USE("xattr", "ext4");
164#endif
165#ifdef CONFIG_JFS_SECURITY
166 FS_USE("xattr", "jfs");
167#endif
168#ifdef CONFIG_REISERFS_FS_SECURITY
169 FS_USE("xattr", "reiserfs");
170#endif
171#ifdef CONFIG_JFFS2_FS_SECURITY
172 FS_USE("xattr", "jffs2");
173#endif
174#ifdef CONFIG_XFS_FS
175 FS_USE("xattr", "xfs");
176#endif
177#ifdef CONFIG_GFS2_FS
178 FS_USE("xattr", "gfs2");
179#endif
180#ifdef CONFIG_BTRFS_FS
181 FS_USE("xattr", "btrfs");
182#endif
183#ifdef CONFIG_F2FS_FS_SECURITY
184 FS_USE("xattr", "f2fs");
185#endif
186#ifdef CONFIG_OCFS2_FS
187 FS_USE("xattr", "ocsfs2");
188#endif
189#ifdef CONFIG_OVERLAY_FS
190 FS_USE("xattr", "overlay");
191#endif
192#ifdef CONFIG_SQUASHFS_XATTR
193 FS_USE("xattr", "squashfs");
194#endif
195
196 /*
197 * Filesystems whose inodes are labeled from allocating task.
198 */
199 FS_USE("task", "pipefs");
200 FS_USE("task", "sockfs");
127 201
128 fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n"); 202 /*
129 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); 203 * Filesystems whose inode labels are computed from both
130 fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); 204 * the allocating task and the superblock label.
205 */
206#ifdef CONFIG_UNIX98_PTYS
207 FS_USE("trans", "devpts");
208#endif
209#ifdef CONFIG_HUGETLBFS
210 FS_USE("trans", "hugetlbfs");
211#endif
212#ifdef CONFIG_TMPFS
213 FS_USE("trans", "tmpfs");
214#endif
215#ifdef CONFIG_DEVTMPFS
216 FS_USE("trans", "devtmpfs");
217#endif
218#ifdef CONFIG_POSIX_MQUEUE
219 FS_USE("trans", "mqueue");
220#endif
131 221
132 fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n"); 222#define GENFSCON(fstype, prefix) \
133 fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); 223 fprintf(fout, "genfscon %s %s " OBJUSERROLETYPE "%s\n", \
134 fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n"); 224 fstype, prefix, mls ? ":" SYSTEMLOW : "")
135 fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
136 fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
137 225
138 fprintf(fout, "genfscon proc / user_u:base_r:base_t\n"); 226 /*
227 * Filesystems whose inodes are labeled from path prefix match
228 * relative to the filesystem root. Depending on the filesystem,
229 * only a single label for all inodes may be supported. Here
230 * we list the filesystem types for which per-file labeling is
231 * supported using genfscon; any other filesystem type can also
232 * be added by only with a single entry for all of its inodes.
233 */
234#ifdef CONFIG_PROC_FS
235 GENFSCON("proc", "/");
236#endif
237#ifdef CONFIG_SECURITY_SELINUX
238 GENFSCON("selinuxfs", "/");
239#endif
240#ifdef CONFIG_SYSFS
241 GENFSCON("sysfs", "/");
242#endif
243#ifdef CONFIG_DEBUG_FS
244 GENFSCON("debugfs", "/");
245#endif
246#ifdef CONFIG_TRACING
247 GENFSCON("tracefs", "/");
248#endif
249#ifdef CONFIG_PSTORE
250 GENFSCON("pstore", "/");
251#endif
252 GENFSCON("cgroup", "/");
253 GENFSCON("cgroup2", "/");
139 254
140 fclose(fout); 255 fclose(fout);
141 256
@@ -144,8 +259,8 @@ int main(int argc, char *argv[])
144 printf("Wrote policy, but cannot open %s for writing\n", ctxout); 259 printf("Wrote policy, but cannot open %s for writing\n", ctxout);
145 usage(argv[0]); 260 usage(argv[0]);
146 } 261 }
147 fprintf(fout, "/ user_u:base_r:base_t\n"); 262 fprintf(fout, "/ " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : "");
148 fprintf(fout, "/.* user_u:base_r:base_t\n"); 263 fprintf(fout, "/.* " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : "");
149 fclose(fout); 264 fclose(fout);
150 265
151 return 0; 266 return 0;