diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Makefile.build | 3 | ||||
-rw-r--r-- | scripts/Makefile.ubsan | 1 | ||||
-rw-r--r-- | scripts/gcc-plugins/Kconfig | 126 | ||||
-rwxr-xr-x | scripts/selinux/install_policy.sh | 92 | ||||
-rw-r--r-- | scripts/selinux/mdp/Makefile | 2 | ||||
-rw-r--r-- | scripts/selinux/mdp/mdp.c | 165 |
6 files changed, 204 insertions, 185 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 76ca30cc4791..0c5969fa795f 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -222,6 +222,9 @@ endif ifdef CONFIG_RETPOLINE objtool_args += --retpoline endif +ifdef CONFIG_X86_SMAP + objtool_args += --uaccess +endif # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index 38b2b4818e8e..019771b845c5 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -3,7 +3,6 @@ ifdef CONFIG_UBSAN CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift) CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero) CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=vla-bound) CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow) CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds) CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size) diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index 74271dba4f94..80220ed26a35 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -13,17 +13,19 @@ config HAVE_GCC_PLUGINS An arch should select this symbol if it supports building with GCC plugins. -menuconfig GCC_PLUGINS - bool "GCC plugins" +config GCC_PLUGINS + bool depends on HAVE_GCC_PLUGINS depends on PLUGIN_HOSTCC != "" + default y help GCC plugins are loadable modules that provide extra features to the compiler. They are useful for runtime instrumentation and static analysis. See Documentation/gcc-plugins.txt for details. -if GCC_PLUGINS +menu "GCC plugins" + depends on GCC_PLUGINS config GCC_PLUGIN_CYC_COMPLEXITY bool "Compute the cyclomatic complexity of a function" if EXPERT @@ -66,71 +68,6 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ -config GCC_PLUGIN_STRUCTLEAK - bool "Zero initialize stack variables" - help - While the kernel is built with warnings enabled for any missed - stack variable initializations, this warning is silenced for - anything passed by reference to another function, under the - occasionally misguided assumption that the function will do - the initialization. As this regularly leads to exploitable - flaws, this plugin is available to identify and zero-initialize - such variables, depending on the chosen level of coverage. - - This plugin was originally ported from grsecurity/PaX. More - information at: - * https://grsecurity.net/ - * https://pax.grsecurity.net/ - -choice - prompt "Coverage" - depends on GCC_PLUGIN_STRUCTLEAK - default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL - help - This chooses the level of coverage over classes of potentially - uninitialized variables. The selected class will be - zero-initialized before use. - - config GCC_PLUGIN_STRUCTLEAK_USER - bool "structs marked for userspace" - help - Zero-initialize any structures on the stack containing - a __user attribute. This can prevent some classes of - uninitialized stack variable exploits and information - exposures, like CVE-2013-2141: - https://git.kernel.org/linus/b9e146d8eb3b9eca - - config GCC_PLUGIN_STRUCTLEAK_BYREF - bool "structs passed by reference" - help - Zero-initialize any structures on the stack that may - be passed by reference and had not already been - explicitly initialized. This can prevent most classes - of uninitialized stack variable exploits and information - exposures, like CVE-2017-1000410: - https://git.kernel.org/linus/06e7e776ca4d3654 - - config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL - bool "anything passed by reference" - help - Zero-initialize any stack variables that may be passed - by reference and had not already been explicitly - initialized. This is intended to eliminate all classes - of uninitialized stack variable exploits and information - exposures. - -endchoice - -config GCC_PLUGIN_STRUCTLEAK_VERBOSE - bool "Report forcefully initialized variables" - depends on GCC_PLUGIN_STRUCTLEAK - depends on !COMPILE_TEST # too noisy - help - This option will cause a warning to be printed each time the - structleak plugin finds a variable it thinks needs to be - initialized. Since not all existing initializers are detected - by the plugin, this can produce false positive warnings. - config GCC_PLUGIN_RANDSTRUCT bool "Randomize layout of sensitive kernel structures" select MODVERSIONS if MODULES @@ -171,59 +108,8 @@ config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE in structures. This reduces the performance hit of RANDSTRUCT at the cost of weakened randomization. -config GCC_PLUGIN_STACKLEAK - bool "Erase the kernel stack before returning from syscalls" - depends on GCC_PLUGINS - depends on HAVE_ARCH_STACKLEAK - help - This option makes the kernel erase the kernel stack before - returning from system calls. That reduces the information which - kernel stack leak bugs can reveal and blocks some uninitialized - stack variable attacks. - - The tradeoff is the performance impact: on a single CPU system kernel - compilation sees a 1% slowdown, other systems and workloads may vary - and you are advised to test this feature on your expected workload - before deploying it. - - This plugin was ported from grsecurity/PaX. More information at: - * https://grsecurity.net/ - * https://pax.grsecurity.net/ - -config STACKLEAK_TRACK_MIN_SIZE - int "Minimum stack frame size of functions tracked by STACKLEAK" - default 100 - range 0 4096 - depends on GCC_PLUGIN_STACKLEAK - help - The STACKLEAK gcc plugin instruments the kernel code for tracking - the lowest border of the kernel stack (and for some other purposes). - It inserts the stackleak_track_stack() call for the functions with - a stack frame size greater than or equal to this parameter. - If unsure, leave the default value 100. - -config STACKLEAK_METRICS - bool "Show STACKLEAK metrics in the /proc file system" - depends on GCC_PLUGIN_STACKLEAK - depends on PROC_FS - help - If this is set, STACKLEAK metrics for every task are available in - the /proc file system. In particular, /proc/<pid>/stack_depth - shows the maximum kernel stack consumption for the current and - previous syscalls. Although this information is not precise, it - can be useful for estimating the STACKLEAK performance impact for - your workloads. - -config STACKLEAK_RUNTIME_DISABLE - bool "Allow runtime disabling of kernel stack erasing" - depends on GCC_PLUGIN_STACKLEAK - help - This option provides 'stack_erasing' sysctl, which can be used in - runtime to control kernel stack erasing for kernels built with - CONFIG_GCC_PLUGIN_STACKLEAK. - config GCC_PLUGIN_ARM_SSP_PER_TASK bool depends on GCC_PLUGINS && ARM -endif +endmenu 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 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 +set -e if [ `id -u` -ne 0 ]; then echo "$0: must be root to install the selinux policy" exit 1 fi + SF=`which setfiles` if [ $? -eq 1 ]; then - if [ -f /sbin/setfiles ]; then - SF="/usr/setfiles" - else - echo "no selinux tools installed: setfiles" - exit 1 - fi + echo "Could not find setfiles" + echo "Do you have policycoreutils installed?" + exit 1 fi -cd mdp - CP=`which checkpolicy` +if [ $? -eq 1 ]; then + echo "Could not find checkpolicy" + echo "Do you have checkpolicy installed?" + exit 1 +fi VERS=`$CP -V | awk '{print $1}'` -./mdp policy.conf file_contexts -$CP -o policy.$VERS policy.conf +ENABLED=`which selinuxenabled` +if [ $? -eq 1 ]; then + echo "Could not find selinuxenabled" + echo "Do you have libselinux-utils installed?" + exit 1 +fi + +if selinuxenabled; then + echo "SELinux is already enabled" + echo "This prevents safely relabeling all files." + echo "Boot with selinux=0 on the kernel command-line or" + echo "SELINUX=disabled in /etc/selinux/config." + exit 1 +fi + +cd mdp +./mdp -m policy.conf file_contexts +$CP -U allow -M -o policy.$VERS policy.conf mkdir -p /etc/selinux/dummy/policy mkdir -p /etc/selinux/dummy/contexts/files +echo "__default__:user_u:s0" > /etc/selinux/dummy/seusers +echo "base_r:base_t:s0" > /etc/selinux/dummy/contexts/failsafe_context +echo "base_r:base_t:s0 base_r:base_t:s0" > /etc/selinux/dummy/default_contexts +cat > /etc/selinux/dummy/contexts/x_contexts <<EOF +client * user_u:base_r:base_t:s0 +property * user_u:object_r:base_t:s0 +extension * user_u:object_r:base_t:s0 +selection * user_u:object_r:base_t:s0 +event * user_u:object_r:base_t:s0 +EOF +touch /etc/selinux/dummy/contexts/virtual_domain_context +touch /etc/selinux/dummy/contexts/virtual_image_context + cp file_contexts /etc/selinux/dummy/contexts/files cp dbus_contexts /etc/selinux/dummy/contexts cp policy.$VERS /etc/selinux/dummy/policy @@ -33,37 +64,22 @@ FC_FILE=/etc/selinux/dummy/contexts/files/file_contexts if [ ! -d /etc/selinux ]; then mkdir -p /etc/selinux fi -if [ ! -f /etc/selinux/config ]; then - cat > /etc/selinux/config << EOF -SELINUX=enforcing +if [ -f /etc/selinux/config ]; then + echo "/etc/selinux/config exists, moving to /etc/selinux/config.bak." + mv /etc/selinux/config /etc/selinux/config.bak +fi +echo "Creating new /etc/selinux/config for dummy policy." +cat > /etc/selinux/config << EOF +SELINUX=permissive SELINUXTYPE=dummy EOF -else - TYPE=`cat /etc/selinux/config | grep "^SELINUXTYPE" | tail -1 | awk -F= '{ print $2 '}` - if [ "eq$TYPE" != "eqdummy" ]; then - selinuxenabled - if [ $? -eq 0 ]; then - echo "SELinux already enabled with a non-dummy policy." - echo "Exiting. Please install policy by hand if that" - echo "is what you REALLY want." - exit 1 - fi - mv /etc/selinux/config /etc/selinux/config.mdpbak - grep -v "^SELINUXTYPE" /etc/selinux/config.mdpbak >> /etc/selinux/config - echo "SELINUXTYPE=dummy" >> /etc/selinux/config - fi -fi cd /etc/selinux/dummy/contexts/files -$SF file_contexts / +$SF -F file_contexts / -mounts=`cat /proc/$$/mounts | egrep "ext2|ext3|xfs|jfs|ext4|ext4dev|gfs2" | awk '{ print $2 '}` -$SF file_contexts $mounts +mounts=`cat /proc/$$/mounts | \ + egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \ + awk '{ print $2 '}` +$SF -F file_contexts $mounts - -dodev=`cat /proc/$$/mounts | grep "/dev "` -if [ "eq$dodev" != "eq" ]; then - mount --move /dev /mnt - $SF file_contexts /dev - mount --move /mnt /dev -fi +echo "-F" > /.autorelabel diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile index e9c92db7e2a3..8a1269a9d0ba 100644 --- a/scripts/selinux/mdp/Makefile +++ b/scripts/selinux/mdp/Makefile @@ -2,7 +2,7 @@ hostprogs-y := mdp HOST_EXTRACFLAGS += \ -I$(srctree)/include/uapi -I$(srctree)/include \ - -I$(srctree)/security/selinux/include + -I$(srctree)/security/selinux/include -I$(objtree)/include always := $(hostprogs-y) clean-files := policy.* file_contexts diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c index 6d51b74bc679..18fd6143888b 100644 --- a/scripts/selinux/mdp/mdp.c +++ b/scripts/selinux/mdp/mdp.c @@ -32,6 +32,7 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <linux/kconfig.h> static void usage(char *name) { @@ -94,10 +95,31 @@ int main(int argc, char *argv[]) } fprintf(fout, "\n"); - /* NOW PRINT OUT MLS STUFF */ + /* print out mls declarations and constraints */ if (mls) { - printf("MLS not yet implemented\n"); - exit(1); + fprintf(fout, "sensitivity s0;\n"); + fprintf(fout, "sensitivity s1;\n"); + fprintf(fout, "dominance { s0 s1 }\n"); + fprintf(fout, "category c0;\n"); + fprintf(fout, "category c1;\n"); + fprintf(fout, "level s0:c0.c1;\n"); + fprintf(fout, "level s1:c0.c1;\n"); +#define SYSTEMLOW "s0" +#define SYSTEMHIGH "s1:c0.c1" + for (i = 0; secclass_map[i].name; i++) { + struct security_class_mapping *map = &secclass_map[i]; + + fprintf(fout, "mlsconstrain %s {\n", map->name); + for (j = 0; map->perms[j]; j++) + fprintf(fout, "\t%s\n", map->perms[j]); + /* + * This requires all subjects and objects to be + * single-level (l2 eq h2), and that the subject + * level dominate the object level (h1 dom h2) + * in order to have any permissions to it. + */ + fprintf(fout, "} (l2 eq h2 and h1 dom h2);\n\n"); + } } /* types, roles, and allows */ @@ -107,34 +129,127 @@ int main(int argc, char *argv[]) for (i = 0; secclass_map[i].name; i++) fprintf(fout, "allow base_t base_t:%s *;\n", secclass_map[i].name); - fprintf(fout, "user user_u roles { base_r };\n"); - fprintf(fout, "\n"); + fprintf(fout, "user user_u roles { base_r }"); + if (mls) + fprintf(fout, " level %s range %s - %s", SYSTEMLOW, + SYSTEMLOW, SYSTEMHIGH); + fprintf(fout, ";\n"); + +#define SUBJUSERROLETYPE "user_u:base_r:base_t" +#define OBJUSERROLETYPE "user_u:object_r:base_t" /* default sids */ for (i = 1; i < initial_sid_to_string_len; i++) - fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); + fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n", + initial_sid_to_string[i], mls ? ":" SYSTEMLOW : ""); fprintf(fout, "\n"); - fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n"); +#define FS_USE(behavior, fstype) \ + fprintf(fout, "fs_use_%s %s " OBJUSERROLETYPE "%s;\n", \ + behavior, fstype, mls ? ":" SYSTEMLOW : "") + + /* + * Filesystems whose inode labels can be fetched via getxattr. + */ +#ifdef CONFIG_EXT2_FS_SECURITY + FS_USE("xattr", "ext2"); +#endif +#ifdef CONFIG_EXT4_FS_SECURITY +#ifdef CONFIG_EXT4_USE_FOR_EXT2 + FS_USE("xattr", "ext2"); +#endif + FS_USE("xattr", "ext3"); + FS_USE("xattr", "ext4"); +#endif +#ifdef CONFIG_JFS_SECURITY + FS_USE("xattr", "jfs"); +#endif +#ifdef CONFIG_REISERFS_FS_SECURITY + FS_USE("xattr", "reiserfs"); +#endif +#ifdef CONFIG_JFFS2_FS_SECURITY + FS_USE("xattr", "jffs2"); +#endif +#ifdef CONFIG_XFS_FS + FS_USE("xattr", "xfs"); +#endif +#ifdef CONFIG_GFS2_FS + FS_USE("xattr", "gfs2"); +#endif +#ifdef CONFIG_BTRFS_FS + FS_USE("xattr", "btrfs"); +#endif +#ifdef CONFIG_F2FS_FS_SECURITY + FS_USE("xattr", "f2fs"); +#endif +#ifdef CONFIG_OCFS2_FS + FS_USE("xattr", "ocsfs2"); +#endif +#ifdef CONFIG_OVERLAY_FS + FS_USE("xattr", "overlay"); +#endif +#ifdef CONFIG_SQUASHFS_XATTR + FS_USE("xattr", "squashfs"); +#endif + + /* + * Filesystems whose inodes are labeled from allocating task. + */ + FS_USE("task", "pipefs"); + FS_USE("task", "sockfs"); - fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); + /* + * Filesystems whose inode labels are computed from both + * the allocating task and the superblock label. + */ +#ifdef CONFIG_UNIX98_PTYS + FS_USE("trans", "devpts"); +#endif +#ifdef CONFIG_HUGETLBFS + FS_USE("trans", "hugetlbfs"); +#endif +#ifdef CONFIG_TMPFS + FS_USE("trans", "tmpfs"); +#endif +#ifdef CONFIG_DEVTMPFS + FS_USE("trans", "devtmpfs"); +#endif +#ifdef CONFIG_POSIX_MQUEUE + FS_USE("trans", "mqueue"); +#endif - fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n"); +#define GENFSCON(fstype, prefix) \ + fprintf(fout, "genfscon %s %s " OBJUSERROLETYPE "%s\n", \ + fstype, prefix, mls ? ":" SYSTEMLOW : "") - fprintf(fout, "genfscon proc / user_u:base_r:base_t\n"); + /* + * Filesystems whose inodes are labeled from path prefix match + * relative to the filesystem root. Depending on the filesystem, + * only a single label for all inodes may be supported. Here + * we list the filesystem types for which per-file labeling is + * supported using genfscon; any other filesystem type can also + * be added by only with a single entry for all of its inodes. + */ +#ifdef CONFIG_PROC_FS + GENFSCON("proc", "/"); +#endif +#ifdef CONFIG_SECURITY_SELINUX + GENFSCON("selinuxfs", "/"); +#endif +#ifdef CONFIG_SYSFS + GENFSCON("sysfs", "/"); +#endif +#ifdef CONFIG_DEBUG_FS + GENFSCON("debugfs", "/"); +#endif +#ifdef CONFIG_TRACING + GENFSCON("tracefs", "/"); +#endif +#ifdef CONFIG_PSTORE + GENFSCON("pstore", "/"); +#endif + GENFSCON("cgroup", "/"); + GENFSCON("cgroup2", "/"); fclose(fout); @@ -143,8 +258,8 @@ int main(int argc, char *argv[]) printf("Wrote policy, but cannot open %s for writing\n", ctxout); usage(argv[0]); } - fprintf(fout, "/ user_u:base_r:base_t\n"); - fprintf(fout, "/.* user_u:base_r:base_t\n"); + fprintf(fout, "/ " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : ""); + fprintf(fout, "/.* " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : ""); fclose(fout); return 0; |