⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hooks.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  NSA Security-Enhanced Linux (SELinux) security module * *  This file contains the SELinux hook function implementations. * *  Authors:  Stephen Smalley, <sds@epoch.ncsc.mil> *            Chris Vance, <cvance@nai.com> *            Wayne Salamon, <wsalamon@nai.com> *            James Morris <jmorris@redhat.com> * *  Copyright (C) 2001,2002 Networks Associates Technology, Inc. *  Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License version 2, *      as published by the Free Software Foundation. */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/ptrace.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/security.h>#include <linux/xattr.h>#include <linux/capability.h>#include <linux/unistd.h>#include <linux/mm.h>#include <linux/mman.h>#include <linux/slab.h>#include <linux/pagemap.h>#include <linux/swap.h>#include <linux/smp_lock.h>#include <linux/spinlock.h>#include <linux/syscalls.h>#include <linux/file.h>#include <linux/namei.h>#include <linux/mount.h>#include <linux/ext2_fs.h>#include <linux/proc_fs.h>#include <linux/kd.h>#include <linux/netfilter_ipv4.h>#include <linux/netfilter_ipv6.h>#include <linux/tty.h>#include <net/icmp.h>#include <net/ip.h>		/* for sysctl_local_port_range[] */#include <net/tcp.h>		/* struct or_callable used in sock_rcv_skb */#include <asm/uaccess.h>#include <asm/semaphore.h>#include <asm/ioctls.h>#include <linux/bitops.h>#include <linux/interrupt.h>#include <linux/netdevice.h>	/* for network interface checks */#include <linux/netlink.h>#include <linux/tcp.h>#include <linux/udp.h>#include <linux/quota.h>#include <linux/un.h>		/* for Unix socket types */#include <net/af_unix.h>	/* for Unix socket types */#include <linux/parser.h>#include <linux/nfs_mount.h>#include <net/ipv6.h>#include <linux/hugetlb.h>#include <linux/personality.h>#include "avc.h"#include "objsec.h"#include "netif.h"#define XATTR_SELINUX_SUFFIX "selinux"#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIXextern int policydb_loaded_version;extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);#ifdef CONFIG_SECURITY_SELINUX_DEVELOPint selinux_enforcing = 0;static int __init enforcing_setup(char *str){	selinux_enforcing = simple_strtol(str,NULL,0);	return 1;}__setup("enforcing=", enforcing_setup);#endif#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAMint selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE;static int __init selinux_enabled_setup(char *str){	selinux_enabled = simple_strtol(str, NULL, 0);	return 1;}__setup("selinux=", selinux_enabled_setup);#endif/* Original (dummy) security module. */static struct security_operations *original_ops = NULL;/* Minimal support for a secondary security module,   just to allow the use of the dummy or capability modules.   The owlsm module can alternatively be used as a secondary   module as long as CONFIG_OWLSM_FD is not enabled. */static struct security_operations *secondary_ops = NULL;/* Lists of inode and superblock security structures initialized   before the policy was loaded. */static LIST_HEAD(superblock_security_head);static spinlock_t sb_security_lock = SPIN_LOCK_UNLOCKED;/* Allocate and free functions for each kind of security blob. */static int task_alloc_security(struct task_struct *task){	struct task_security_struct *tsec;	tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL);	if (!tsec)		return -ENOMEM;	memset(tsec, 0, sizeof(struct task_security_struct));	tsec->magic = SELINUX_MAGIC;	tsec->task = task;	tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;	task->security = tsec;	return 0;}static void task_free_security(struct task_struct *task){	struct task_security_struct *tsec = task->security;	if (!tsec || tsec->magic != SELINUX_MAGIC)		return;	task->security = NULL;	kfree(tsec);}static int inode_alloc_security(struct inode *inode){	struct task_security_struct *tsec = current->security;	struct inode_security_struct *isec;	isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL);	if (!isec)		return -ENOMEM;	memset(isec, 0, sizeof(struct inode_security_struct));	init_MUTEX(&isec->sem);	INIT_LIST_HEAD(&isec->list);	isec->magic = SELINUX_MAGIC;	isec->inode = inode;	isec->sid = SECINITSID_UNLABELED;	isec->sclass = SECCLASS_FILE;	if (tsec && tsec->magic == SELINUX_MAGIC)		isec->task_sid = tsec->sid;	else		isec->task_sid = SECINITSID_UNLABELED;	inode->i_security = isec;	return 0;}static void inode_free_security(struct inode *inode){	struct inode_security_struct *isec = inode->i_security;	struct superblock_security_struct *sbsec = inode->i_sb->s_security;	if (!isec || isec->magic != SELINUX_MAGIC)		return;	spin_lock(&sbsec->isec_lock);	if (!list_empty(&isec->list))		list_del_init(&isec->list);	spin_unlock(&sbsec->isec_lock);	inode->i_security = NULL;	kfree(isec);}static int file_alloc_security(struct file *file){	struct task_security_struct *tsec = current->security;	struct file_security_struct *fsec;	fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC);	if (!fsec)		return -ENOMEM;	memset(fsec, 0, sizeof(struct file_security_struct));	fsec->magic = SELINUX_MAGIC;	fsec->file = file;	if (tsec && tsec->magic == SELINUX_MAGIC) {		fsec->sid = tsec->sid;		fsec->fown_sid = tsec->sid;	} else {		fsec->sid = SECINITSID_UNLABELED;		fsec->fown_sid = SECINITSID_UNLABELED;	}	file->f_security = fsec;	return 0;}static void file_free_security(struct file *file){	struct file_security_struct *fsec = file->f_security;	if (!fsec || fsec->magic != SELINUX_MAGIC)		return;	file->f_security = NULL;	kfree(fsec);}static int superblock_alloc_security(struct super_block *sb){	struct superblock_security_struct *sbsec;	sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);	if (!sbsec)		return -ENOMEM;	memset(sbsec, 0, sizeof(struct superblock_security_struct));	init_MUTEX(&sbsec->sem);	INIT_LIST_HEAD(&sbsec->list);	INIT_LIST_HEAD(&sbsec->isec_head);	spin_lock_init(&sbsec->isec_lock);	sbsec->magic = SELINUX_MAGIC;	sbsec->sb = sb;	sbsec->sid = SECINITSID_UNLABELED;	sbsec->def_sid = SECINITSID_FILE;	sb->s_security = sbsec;	return 0;}static void superblock_free_security(struct super_block *sb){	struct superblock_security_struct *sbsec = sb->s_security;	if (!sbsec || sbsec->magic != SELINUX_MAGIC)		return;	spin_lock(&sb_security_lock);	if (!list_empty(&sbsec->list))		list_del_init(&sbsec->list);	spin_unlock(&sb_security_lock);	sb->s_security = NULL;	kfree(sbsec);}#ifdef CONFIG_SECURITY_NETWORKstatic int sk_alloc_security(struct sock *sk, int family, int priority){	struct sk_security_struct *ssec;	if (family != PF_UNIX)		return 0;	ssec = kmalloc(sizeof(*ssec), priority);	if (!ssec)		return -ENOMEM;	memset(ssec, 0, sizeof(*ssec));	ssec->magic = SELINUX_MAGIC;	ssec->sk = sk;	ssec->peer_sid = SECINITSID_UNLABELED;	sk->sk_security = ssec;	return 0;}static void sk_free_security(struct sock *sk){	struct sk_security_struct *ssec = sk->sk_security;	if (sk->sk_family != PF_UNIX || ssec->magic != SELINUX_MAGIC)		return;	sk->sk_security = NULL;	kfree(ssec);}#endif	/* CONFIG_SECURITY_NETWORK *//* The security server must be initialized before   any labeling or access decisions can be provided. */extern int ss_initialized;/* The file system's label must be initialized prior to use. */static char *labeling_behaviors[6] = {	"uses xattr",	"uses transition SIDs",	"uses task SIDs",	"uses genfs_contexts",	"not configured for labeling",	"uses mountpoint labeling",};static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);static inline int inode_doinit(struct inode *inode){	return inode_doinit_with_dentry(inode, NULL);}enum {	Opt_context = 1,	Opt_fscontext = 2,	Opt_defcontext = 4,};static match_table_t tokens = {	{Opt_context, "context=%s"},	{Opt_fscontext, "fscontext=%s"},	{Opt_defcontext, "defcontext=%s"},};#define SEL_MOUNT_FAIL_MSG "SELinux:  duplicate or incompatible mount options\n"static int try_context_mount(struct super_block *sb, void *data){	char *context = NULL, *defcontext = NULL;	const char *name;	u32 sid;	int alloc = 0, rc = 0, seen = 0;	struct task_security_struct *tsec = current->security;	struct superblock_security_struct *sbsec = sb->s_security;	if (!data)		goto out;	name = sb->s_type->name;	if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) {		/* NFS we understand. */		if (!strcmp(name, "nfs")) {			struct nfs_mount_data *d = data;			if (d->version <  NFS_MOUNT_VERSION)				goto out;			if (d->context[0]) {				context = d->context;				seen |= Opt_context;			}		} else			goto out;	} else {		/* Standard string-based options. */		char *p, *options = data;		while ((p = strsep(&options, ",")) != NULL) {			int token;			substring_t args[MAX_OPT_ARGS];			if (!*p)				continue;			token = match_token(p, tokens, args);			switch (token) {			case Opt_context:				if (seen) {					rc = -EINVAL;					printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);					goto out_free;				}				context = match_strdup(&args[0]);				if (!context) {					rc = -ENOMEM;					goto out_free;				}				if (!alloc)					alloc = 1;				seen |= Opt_context;				break;			case Opt_fscontext:				if (sbsec->behavior != SECURITY_FS_USE_XATTR) {					rc = -EINVAL;					printk(KERN_WARNING "SELinux:  "					       "fscontext option is invalid for"					       " this filesystem type\n");					goto out_free;				}				if (seen & (Opt_context|Opt_fscontext)) {					rc = -EINVAL;					printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);					goto out_free;				}				context = match_strdup(&args[0]);				if (!context) {					rc = -ENOMEM;					goto out_free;				}				if (!alloc)					alloc = 1;				seen |= Opt_fscontext;				break;			case Opt_defcontext:				if (sbsec->behavior != SECURITY_FS_USE_XATTR) {					rc = -EINVAL;					printk(KERN_WARNING "SELinux:  "					       "defcontext option is invalid "					       "for this filesystem type\n");					goto out_free;				}				if (seen & (Opt_context|Opt_defcontext)) {					rc = -EINVAL;					printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);					goto out_free;				}				defcontext = match_strdup(&args[0]);				if (!defcontext) {					rc = -ENOMEM;					goto out_free;				}				if (!alloc)					alloc = 1;				seen |= Opt_defcontext;				break;			default:				rc = -EINVAL;				printk(KERN_WARNING "SELinux:  unknown mount "				       "option\n");				goto out_free;			}		}	}	if (!seen)		goto out;	if (context) {		rc = security_context_to_sid(context, strlen(context), &sid);		if (rc) {			printk(KERN_WARNING "SELinux: security_context_to_sid"			       "(%s) failed for (dev %s, type %s) errno=%d\n",			       context, sb->s_id, name, rc);			goto out_free;		}		rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,		                  FILESYSTEM__RELABELFROM, NULL, NULL);		if (rc)			goto out_free;		rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,		                  FILESYSTEM__RELABELTO, NULL, NULL);		if (rc)			goto out_free;		sbsec->sid = sid;		if (seen & Opt_context)			sbsec->behavior = SECURITY_FS_USE_MNTPOINT;	}	if (defcontext) {		rc = security_context_to_sid(defcontext, strlen(defcontext), &sid);		if (rc) {			printk(KERN_WARNING "SELinux: security_context_to_sid"			       "(%s) failed for (dev %s, type %s) errno=%d\n",			       defcontext, sb->s_id, name, rc);			goto out_free;		}		if (sid == sbsec->def_sid)			goto out_free;		rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,				  FILESYSTEM__RELABELFROM, NULL, NULL);		if (rc)			goto out_free;		rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,				  FILESYSTEM__ASSOCIATE, NULL, NULL);		if (rc)			goto out_free;		sbsec->def_sid = sid;	}out_free:	if (alloc) {		kfree(context);		kfree(defcontext);	}out:	return rc;}static int superblock_doinit(struct super_block *sb, void *data){	struct superblock_security_struct *sbsec = sb->s_security;	struct dentry *root = sb->s_root;	struct inode *inode = root->d_inode;	int rc = 0;	down(&sbsec->sem);	if (sbsec->initialized)		goto out;	if (!ss_initialized) {		/* Defer initialization until selinux_complete_init,		   after the initial policy is loaded and the security		   server is ready to handle calls. */		spin_lock(&sb_security_lock);		if (list_empty(&sbsec->list))			list_add(&sbsec->list, &superblock_security_head);		spin_unlock(&sb_security_lock);		goto out;	}	/* Determine the labeling behavior to use for this filesystem type. */	rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid);	if (rc) {		printk(KERN_WARNING "%s:  security_fs_use(%s) returned %d\n",		       __FUNCTION__, sb->s_type->name, rc);		goto out;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -