diff options
Diffstat (limited to 'security')
87 files changed, 8706 insertions, 2444 deletions
diff --git a/security/Kconfig b/security/Kconfig index 93027fdf47d1..e8e449444e65 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -54,6 +54,15 @@ config SECURITY_NETWORK implement socket and networking access controls. If you are unsure how to answer this question, answer N. +config SECURITY_INFINIBAND + bool "Infiniband Security Hooks" + depends on SECURITY && INFINIBAND + help + This enables the Infiniband security hooks. + If enabled, a security module can use these hooks to + implement Infiniband access controls. + If you are unsure how to answer this question, answer N. + config SECURITY_NETWORK_XFRM bool "XFRM (IPSec) Networking Security Hooks" depends on XFRM && SECURITY_NETWORK @@ -139,7 +148,7 @@ config HARDENED_USERCOPY copying memory to/from the kernel (via copy_to_user() and copy_from_user() functions) by rejecting memory ranges that are larger than the specified heap object, span multiple - separately allocates pages, are not on the process stack, + separately allocated pages, are not on the process stack, or are part of the kernel text. This kills entire classes of heap overflow exploits and similar kernel memory exposures. @@ -154,6 +163,13 @@ config HARDENED_USERCOPY_PAGESPAN been removed. This config is intended to be used only while trying to find such users. +config FORTIFY_SOURCE + bool "Harden common str/mem functions against buffer overflows" + depends on ARCH_HAS_FORTIFY_SOURCE + help + Detect overflows of buffers in common string and memory functions + where the compiler can determine and validate the buffer sizes. + config STATIC_USERMODEHELPER bool "Force all usermode helper calls through a single binary" help diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile index ad369a7aac24..a16b195274de 100644 --- a/security/apparmor/Makefile +++ b/security/apparmor/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ - resource.o secid.o file.o policy_ns.o + resource.o secid.o file.o policy_ns.o label.o apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o clean-files := capability_names.h rlim_names.h @@ -20,7 +20,7 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\ sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \ -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\ echo "};" >> $@ ;\ - echo -n '\#define AA_FS_CAPS_MASK "' >> $@ ;\ + printf '%s' '\#define AA_SFS_CAPS_MASK "' >> $@ ;\ sed $< -r -n -e '/CAP_FS_MASK/d' \ -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \ tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ @@ -46,7 +46,7 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\ # #define RLIMIT_FSIZE 1 /* Maximum filesize */ # #define RLIMIT_STACK 3 /* max stack size */ # to -# #define AA_FS_RLIMIT_MASK "fsize stack" +# #define AA_SFS_RLIMIT_MASK "fsize stack" quiet_cmd_make-rlim = GEN $@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \ > $@ ;\ @@ -56,7 +56,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \ echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\ sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\ echo "};" >> $@ ; \ - echo -n '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\ + printf '%s' '\#define AA_SFS_RLIMIT_MASK "' >> $@ ;\ sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \ tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index 4f6ac9dbc65d..853c2ec8e0c9 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -22,19 +22,52 @@ #include <linux/namei.h> #include <linux/capability.h> #include <linux/rcupdate.h> -#include <uapi/linux/major.h> #include <linux/fs.h> +#include <linux/poll.h> +#include <uapi/linux/major.h> +#include <uapi/linux/magic.h> #include "include/apparmor.h" #include "include/apparmorfs.h" #include "include/audit.h" #include "include/context.h" #include "include/crypto.h" +#include "include/policy_ns.h" +#include "include/label.h" #include "include/policy.h" #include "include/policy_ns.h" #include "include/resource.h" #include "include/policy_unpack.h" +/* + * The apparmor filesystem interface used for policy load and introspection + * The interface is split into two main components based on their function + * a securityfs component: + * used for static files that are always available, and which allows + * userspace to specificy the location of the security filesystem. + * + * fns and data are prefixed with + * aa_sfs_ + * + * an apparmorfs component: + * used loaded policy content and introspection. It is not part of a + * regular mounted filesystem and is available only through the magic + * policy symlink in the root of the securityfs apparmor/ directory. + * Tasks queries will be magically redirected to the correct portion + * of the policy tree based on their confinement. + * + * fns and data are prefixed with + * aafs_ + * + * The aa_fs_ prefix is used to indicate the fn is used by both the + * securityfs and apparmorfs filesystems. + */ + + +/* + * support fns + */ + /** * aa_mangle_name - mangle a profile name to std profile layout form * @name: profile name to mangle (NOT NULL) @@ -74,6 +107,265 @@ static int mangle_name(const char *name, char *target) return t - target; } + +/* + * aafs - core fns and data for the policy tree + */ + +#define AAFS_NAME "apparmorfs" +static struct vfsmount *aafs_mnt; +static int aafs_count; + + +static int aafs_show_path(struct seq_file *seq, struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + + seq_printf(seq, "%s:[%lu]", AAFS_NAME, inode->i_ino); + return 0; +} + +static void aafs_evict_inode(struct inode *inode) +{ + truncate_inode_pages_final(&inode->i_data); + clear_inode(inode); + if (S_ISLNK(inode->i_mode)) + kfree(inode->i_link); +} + +static const struct super_operations aafs_super_ops = { + .statfs = simple_statfs, + .evict_inode = aafs_evict_inode, + .show_path = aafs_show_path, +}; + +static int fill_super(struct super_block *sb, void *data, int silent) +{ + static struct tree_descr files[] = { {""} }; + int error; + + error = simple_fill_super(sb, AAFS_MAGIC, files); + if (error) + return error; + sb->s_op = &aafs_super_ops; + + return 0; +} + +static struct dentry *aafs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) +{ + return mount_single(fs_type, flags, data, fill_super); +} + +static struct file_system_type aafs_ops = { + .owner = THIS_MODULE, + .name = AAFS_NAME, + .mount = aafs_mount, + .kill_sb = kill_anon_super, +}; + +/** + * __aafs_setup_d_inode - basic inode setup for apparmorfs + * @dir: parent directory for the dentry + * @dentry: dentry we are seting the inode up for + * @mode: permissions the file should have + * @data: data to store on inode.i_private, available in open() + * @link: if symlink, symlink target string + * @fops: struct file_operations that should be used + * @iops: struct of inode_operations that should be used + */ +static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry, + umode_t mode, void *data, char *link, + const struct file_operations *fops, + const struct inode_operations *iops) +{ + struct inode *inode = new_inode(dir->i_sb); + + AA_BUG(!dir); + AA_BUG(!dentry); + + if (!inode) + return -ENOMEM; + + inode->i_ino = get_next_ino(); + inode->i_mode = mode; + inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); + inode->i_private = data; + if (S_ISDIR(mode)) { + inode->i_op = iops ? iops : &simple_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + inc_nlink(inode); + inc_nlink(dir); + } else if (S_ISLNK(mode)) { + inode->i_op = iops ? iops : &simple_symlink_inode_operations; + inode->i_link = link; + } else { + inode->i_fop = fops; + } + d_instantiate(dentry, inode); + dget(dentry); + + return 0; +} + +/** + * aafs_create - create a dentry in the apparmorfs filesystem + * + * @name: name of dentry to create + * @mode: permissions the file should have + * @parent: parent directory for this dentry + * @data: data to store on inode.i_private, available in open() + * @link: if symlink, symlink target string + * @fops: struct file_operations that should be used for + * @iops: struct of inode_operations that should be used + * + * This is the basic "create a xxx" function for apparmorfs. + * + * Returns a pointer to a dentry if it succeeds, that must be free with + * aafs_remove(). Will return ERR_PTR on failure. + */ +static struct dentry *aafs_create(const char *name, umode_t mode, + struct dentry *parent, void *data, void *link, + const struct file_operations *fops, + const struct inode_operations *iops) +{ + struct dentry *dentry; + struct inode *dir; + int error; + + AA_BUG(!name); + AA_BUG(!parent); + + if (!(mode & S_IFMT)) + mode = (mode & S_IALLUGO) | S_IFREG; + + error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count); + if (error) + return ERR_PTR(error); + + dir = d_inode(parent); + + inode_lock(dir); + dentry = lookup_one_len(name, parent, strlen(name)); + if (IS_ERR(dentry)) + goto fail_lock; + + if (d_really_is_positive(dentry)) { + error = -EEXIST; + goto fail_dentry; + } + + error = __aafs_setup_d_inode(dir, dentry, mode, data, link, fops, iops); + if (error) + goto fail_dentry; + inode_unlock(dir); + + return dentry; + +fail_dentry: + dput(dentry); + +fail_lock: + inode_unlock(dir); + simple_release_fs(&aafs_mnt, &aafs_count); + + return ERR_PTR(error); +} + +/** + * aafs_create_file - create a file in the apparmorfs filesystem + * + * @name: name of dentry to create + * @mode: permi |