1705 lines · 42.7 KB · C
RawDownload
/* * Security plug functions * * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com> * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com> * Copyright (C) 2016 Mellanox Technologies * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2 of the License, or *	(at your option) any later version. */ #include <linux/capability.h>#include <linux/dcache.h>#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/lsm_hooks.h>#include <linux/integrity.h>#include <linux/ima.h>#include <linux/evm.h>#include <linux/fsnotify.h>#include <linux/mman.h>#include <linux/mount.h>#include <linux/personality.h>#include <linux/backing-dev.h>#include <linux/string.h>#include <net/flow.h> #define MAX_LSM_EVM_XATTR	2 /* Maximum number of letters for an LSM name string */#define SECURITY_NAME_MAX	10 struct security_hook_heads security_hook_heads __lsm_ro_after_init;static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); char *lsm_names;/* Boot-time LSM user choice */static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =	CONFIG_DEFAULT_SECURITY; static void __init do_security_initcalls(void){	initcall_t *call;	call = __security_initcall_start;	while (call < __security_initcall_end) {		(*call) ();		call++;	}} /** * security_init - initializes the security framework * * This should be called early in the kernel initialization sequence. */int __init security_init(void){	int i;	struct list_head *list = (struct list_head *) &security_hook_heads; 	for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct list_head);	     i++)		INIT_LIST_HEAD(&list[i]);	pr_info("Security Framework initialized\n"); 	/*	 * Load minor LSMs, with the capability module always first.	 */	capability_add_hooks();	yama_add_hooks();	loadpin_add_hooks(); 	/*	 * Load all the remaining security modules.	 */	do_security_initcalls(); 	return 0;} /* Save user chosen LSM */static int __init choose_lsm(char *str){	strncpy(chosen_lsm, str, SECURITY_NAME_MAX);	return 1;}__setup("security=", choose_lsm); static bool match_last_lsm(const char *list, const char *lsm){	const char *last; 	if (WARN_ON(!list || !lsm))		return false;	last = strrchr(list, ',');	if (last)		/* Pass the comma, strcmp() will check for '\0' */		last++;	else		last = list;	return !strcmp(last, lsm);} static int lsm_append(char *new, char **result){	char *cp; 	if (*result == NULL) {		*result = kstrdup(new, GFP_KERNEL);	} else {		/* Check if it is the last registered name */		if (match_last_lsm(*result, new))			return 0;		cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new);		if (cp == NULL)			return -ENOMEM;		kfree(*result);		*result = cp;	}	return 0;} /** * security_module_enable - Load given security module on boot ? * @module: the name of the module * * Each LSM must pass this method before registering its own operations * to avoid security registration races. This method may also be used * to check if your LSM is currently loaded during kernel initialization. * * Returns: * * true if: * * - The passed LSM is the one chosen by user at boot time, * - or the passed LSM is configured as the default and the user did not *   choose an alternate LSM at boot time. * * Otherwise, return false. */int __init security_module_enable(const char *module){	return !strcmp(module, chosen_lsm);} /** * security_add_hooks - Add a modules hooks to the hook lists. * @hooks: the hooks to add * @count: the number of hooks to add * @lsm: the name of the security module * * Each LSM has to register its hooks with the infrastructure. */void __init security_add_hooks(struct security_hook_list *hooks, int count,				char *lsm){	int i; 	for (i = 0; i < count; i++) {		hooks[i].lsm = lsm;		list_add_tail_rcu(&hooks[i].list, hooks[i].head);	}	if (lsm_append(lsm, &lsm_names) < 0)		panic("%s - Cannot get early memory.\n", __func__);} int call_lsm_notifier(enum lsm_event event, void *data){	return atomic_notifier_call_chain(&lsm_notifier_chain, event, data);}EXPORT_SYMBOL(call_lsm_notifier); int register_lsm_notifier(struct notifier_block *nb){	return atomic_notifier_chain_register(&lsm_notifier_chain, nb);}EXPORT_SYMBOL(register_lsm_notifier); int unregister_lsm_notifier(struct notifier_block *nb){	return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb);}EXPORT_SYMBOL(unregister_lsm_notifier); /* * Hook list operation macros. * * call_void_hook: *	This is a hook that does not return a value. * * call_int_hook: *	This is a hook that returns a value. */ #define call_void_hook(FUNC, ...)				\	do {							\		struct security_hook_list *P;			\								\		list_for_each_entry(P, &security_hook_heads.FUNC, list)	\			P->hook.FUNC(__VA_ARGS__);		\	} while (0) #define call_int_hook(FUNC, IRC, ...) ({			\	int RC = IRC;						\	do {							\		struct security_hook_list *P;			\								\		list_for_each_entry(P, &security_hook_heads.FUNC, list) { \			RC = P->hook.FUNC(__VA_ARGS__);		\			if (RC != 0)				\				break;				\		}						\	} while (0);						\	RC;							\}) /* Security operations */ int security_binder_set_context_mgr(struct task_struct *mgr){	return call_int_hook(binder_set_context_mgr, 0, mgr);} int security_binder_transaction(struct task_struct *from,				struct task_struct *to){	return call_int_hook(binder_transaction, 0, from, to);} int security_binder_transfer_binder(struct task_struct *from,				    struct task_struct *to){	return call_int_hook(binder_transfer_binder, 0, from, to);} int security_binder_transfer_file(struct task_struct *from,				  struct task_struct *to, struct file *file){	return call_int_hook(binder_transfer_file, 0, from, to, file);} int security_ptrace_access_check(struct task_struct *child, unsigned int mode){	return call_int_hook(ptrace_access_check, 0, child, mode);} int security_ptrace_traceme(struct task_struct *parent){	return call_int_hook(ptrace_traceme, 0, parent);} int security_capget(struct task_struct *target,		     kernel_cap_t *effective,		     kernel_cap_t *inheritable,		     kernel_cap_t *permitted){	return call_int_hook(capget, 0, target,				effective, inheritable, permitted);} int security_capset(struct cred *new, const struct cred *old,		    const kernel_cap_t *effective,		    const kernel_cap_t *inheritable,		    const kernel_cap_t *permitted){	return call_int_hook(capset, 0, new, old,				effective, inheritable, permitted);} int security_capable(const struct cred *cred, struct user_namespace *ns,		     int cap){	return call_int_hook(capable, 0, cred, ns, cap, SECURITY_CAP_AUDIT);} int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns,			     int cap){	return call_int_hook(capable, 0, cred, ns, cap, SECURITY_CAP_NOAUDIT);} int security_quotactl(int cmds, int type, int id, struct super_block *sb){	return call_int_hook(quotactl, 0, cmds, type, id, sb);} int security_quota_on(struct dentry *dentry){	return call_int_hook(quota_on, 0, dentry);} int security_syslog(int type){	return call_int_hook(syslog, 0, type);} int security_settime64(const struct timespec64 *ts, const struct timezone *tz){	return call_int_hook(settime, 0, ts, tz);} int security_vm_enough_memory_mm(struct mm_struct *mm, long pages){	struct security_hook_list *hp;	int cap_sys_admin = 1;	int rc; 	/*	 * The module will respond with a positive value if	 * it thinks the __vm_enough_memory() call should be	 * made with the cap_sys_admin set. If all of the modules	 * agree that it should be set it will. If any module	 * thinks it should not be set it won't.	 */	list_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) {		rc = hp->hook.vm_enough_memory(mm, pages);		if (rc <= 0) {			cap_sys_admin = 0;			break;		}	}	return __vm_enough_memory(mm, pages, cap_sys_admin);} int security_bprm_set_creds(struct linux_binprm *bprm){	return call_int_hook(bprm_set_creds, 0, bprm);} int security_bprm_check(struct linux_binprm *bprm){	int ret; 	ret = call_int_hook(bprm_check_security, 0, bprm);	if (ret)		return ret;	return ima_bprm_check(bprm);} void security_bprm_committing_creds(struct linux_binprm *bprm){	call_void_hook(bprm_committing_creds, bprm);} void security_bprm_committed_creds(struct linux_binprm *bprm){	call_void_hook(bprm_committed_creds, bprm);} int security_sb_alloc(struct super_block *sb){	return call_int_hook(sb_alloc_security, 0, sb);} void security_sb_free(struct super_block *sb){	call_void_hook(sb_free_security, sb);} int security_sb_copy_data(char *orig, char *copy){	return call_int_hook(sb_copy_data, 0, orig, copy);}EXPORT_SYMBOL(security_sb_copy_data); int security_sb_remount(struct super_block *sb, void *data){	return call_int_hook(sb_remount, 0, sb, data);} int security_sb_kern_mount(struct super_block *sb, int flags, void *data){	return call_int_hook(sb_kern_mount, 0, sb, flags, data);} int security_sb_show_options(struct seq_file *m, struct super_block *sb){	return call_int_hook(sb_show_options, 0, m, sb);} int security_sb_statfs(struct dentry *dentry){	return call_int_hook(sb_statfs, 0, dentry);} int security_sb_mount(const char *dev_name, const struct path *path,                       const char *type, unsigned long flags, void *data){	return call_int_hook(sb_mount, 0, dev_name, path, type, flags, data);} int security_sb_umount(struct vfsmount *mnt, int flags){	return call_int_hook(sb_umount, 0, mnt, flags);} int security_sb_pivotroot(const struct path *old_path, const struct path *new_path){	return call_int_hook(sb_pivotroot, 0, old_path, new_path);} int security_sb_set_mnt_opts(struct super_block *sb,				struct security_mnt_opts *opts,				unsigned long kern_flags,				unsigned long *set_kern_flags){	return call_int_hook(sb_set_mnt_opts,				opts->num_mnt_opts ? -EOPNOTSUPP : 0, sb,				opts, kern_flags, set_kern_flags);}EXPORT_SYMBOL(security_sb_set_mnt_opts); int security_sb_clone_mnt_opts(const struct super_block *oldsb,				struct super_block *newsb,				unsigned long kern_flags,				unsigned long *set_kern_flags){	return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb,				kern_flags, set_kern_flags);}EXPORT_SYMBOL(security_sb_clone_mnt_opts); int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts){	return call_int_hook(sb_parse_opts_str, 0, options, opts);}EXPORT_SYMBOL(security_sb_parse_opts_str); int security_inode_alloc(struct inode *inode){	inode->i_security = NULL;	return call_int_hook(inode_alloc_security, 0, inode);} void security_inode_free(struct inode *inode){	integrity_inode_free(inode);	call_void_hook(inode_free_security, inode);} int security_dentry_init_security(struct dentry *dentry, int mode,					const struct qstr *name, void **ctx,					u32 *ctxlen){	return call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode,				name, ctx, ctxlen);}EXPORT_SYMBOL(security_dentry_init_security); int security_dentry_create_files_as(struct dentry *dentry, int mode,				    struct qstr *name,				    const struct cred *old, struct cred *new){	return call_int_hook(dentry_create_files_as, 0, dentry, mode,				name, old, new);}EXPORT_SYMBOL(security_dentry_create_files_as); int security_inode_init_security(struct inode *inode, struct inode *dir,				 const struct qstr *qstr,				 const initxattrs initxattrs, void *fs_data){	struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1];	struct xattr *lsm_xattr, *evm_xattr, *xattr;	int ret; 	if (unlikely(IS_PRIVATE(inode)))		return 0; 	if (!initxattrs)		return call_int_hook(inode_init_security, -EOPNOTSUPP, inode,				     dir, qstr, NULL, NULL, NULL);	memset(new_xattrs, 0, sizeof(new_xattrs));	lsm_xattr = new_xattrs;	ret = call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, qstr,						&lsm_xattr->name,						&lsm_xattr->value,						&lsm_xattr->value_len);	if (ret)		goto out; 	evm_xattr = lsm_xattr + 1;	ret = evm_inode_init_security(inode, lsm_xattr, evm_xattr);	if (ret)		goto out;	ret = initxattrs(inode, new_xattrs, fs_data);out:	for (xattr = new_xattrs; xattr->value != NULL; xattr++)		kfree(xattr->value);	return (ret == -EOPNOTSUPP) ? 0 : ret;}EXPORT_SYMBOL(security_inode_init_security); int security_old_inode_init_security(struct inode *inode, struct inode *dir,				     const struct qstr *qstr, const char **name,				     void **value, size_t *len)

Lines 1–500 of 1705.