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

📄 hooks.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (rc)		return rc;	if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {		newsid = tsec->create_sid;	} else {		rc = security_transition_sid(tsec->sid, dsec->sid, tclass,					     &newsid);		if (rc)			return rc;	}	rc = avc_has_perm(tsec->sid, newsid, tclass, FILE__CREATE, NULL, &ad);	if (rc)		return rc;	return avc_has_perm(newsid, sbsec->sid,			    SECCLASS_FILESYSTEM,			    FILESYSTEM__ASSOCIATE, NULL, &ad);}#define MAY_LINK   0#define MAY_UNLINK 1#define MAY_RMDIR  2/* Check whether a task can link, unlink, or rmdir a file/directory. */static int may_link(struct inode *dir,		    struct dentry *dentry,		    int kind){	struct task_security_struct *tsec;	struct inode_security_struct *dsec, *isec;	struct avc_audit_data ad;	u32 av;	int rc;	tsec = current->security;	dsec = dir->i_security;	isec = dentry->d_inode->i_security;	AVC_AUDIT_DATA_INIT(&ad, FS);	ad.u.fs.dentry = dentry;	av = DIR__SEARCH;	av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);	rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR,			  av, &dsec->avcr, &ad);	if (rc)		return rc;	switch (kind) {	case MAY_LINK:		av = FILE__LINK;		break;	case MAY_UNLINK:		av = FILE__UNLINK;		break;	case MAY_RMDIR:		av = DIR__RMDIR;		break;	default:		printk(KERN_WARNING "may_link:  unrecognized kind %d\n", kind);		return 0;	}	rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass,			  av, &isec->avcr, &ad);	return rc;}static inline int may_rename(struct inode *old_dir,			     struct dentry *old_dentry,			     struct inode *new_dir,			     struct dentry *new_dentry){	struct task_security_struct *tsec;	struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;	struct avc_audit_data ad;	u32 av;	int old_is_dir, new_is_dir;	int rc;	tsec = current->security;	old_dsec = old_dir->i_security;	old_isec = old_dentry->d_inode->i_security;	old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);	new_dsec = new_dir->i_security;	AVC_AUDIT_DATA_INIT(&ad, FS);	ad.u.fs.dentry = old_dentry;	rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR,			  DIR__REMOVE_NAME | DIR__SEARCH,			  &old_dsec->avcr, &ad);	if (rc)		return rc;	rc = avc_has_perm(tsec->sid, old_isec->sid,			  old_isec->sclass,			  FILE__RENAME,			  &old_isec->avcr, &ad);	if (rc)		return rc;	if (old_is_dir && new_dir != old_dir) {		rc = avc_has_perm(tsec->sid, old_isec->sid,				  old_isec->sclass,				  DIR__REPARENT,				  &old_isec->avcr, &ad);		if (rc)			return rc;	}	ad.u.fs.dentry = new_dentry;	av = DIR__ADD_NAME | DIR__SEARCH;	if (new_dentry->d_inode)		av |= DIR__REMOVE_NAME;	rc = avc_has_perm(tsec->sid, new_dsec->sid, SECCLASS_DIR,			  av,&new_dsec->avcr, &ad);	if (rc)		return rc;	if (new_dentry->d_inode) {		new_isec = new_dentry->d_inode->i_security;		new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode);		rc = avc_has_perm(tsec->sid, new_isec->sid,				  new_isec->sclass,				  (new_is_dir ? DIR__RMDIR : FILE__UNLINK),				  &new_isec->avcr, &ad);		if (rc)			return rc;	}	return 0;}/* Check whether a task can perform a filesystem operation. */int superblock_has_perm(struct task_struct *tsk,			struct super_block *sb,			u32 perms,			struct avc_audit_data *ad){	struct task_security_struct *tsec;	struct superblock_security_struct *sbsec;	tsec = tsk->security;	sbsec = sb->s_security;	return avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,			    perms, NULL, ad);}/* Convert a Linux mode and permission mask to an access vector. */static inline u32 file_mask_to_av(int mode, int mask){	u32 av = 0;	if ((mode & S_IFMT) != S_IFDIR) {		if (mask & MAY_EXEC)			av |= FILE__EXECUTE;		if (mask & MAY_READ)			av |= FILE__READ;		if (mask & MAY_APPEND)			av |= FILE__APPEND;		else if (mask & MAY_WRITE)			av |= FILE__WRITE;	} else {		if (mask & MAY_EXEC)			av |= DIR__SEARCH;		if (mask & MAY_WRITE)			av |= DIR__WRITE;		if (mask & MAY_READ)			av |= DIR__READ;	}	return av;}/* Convert a Linux file to an access vector. */static inline u32 file_to_av(struct file *file){	u32 av = 0;	if (file->f_mode & FMODE_READ)		av |= FILE__READ;	if (file->f_mode & FMODE_WRITE) {		if (file->f_flags & O_APPEND)			av |= FILE__APPEND;		else			av |= FILE__WRITE;	}	return av;}/* Set an inode's SID to a specified value. */int inode_security_set_sid(struct inode *inode, u32 sid){	struct inode_security_struct *isec = inode->i_security;	struct superblock_security_struct *sbsec = inode->i_sb->s_security;	if (!sbsec->initialized) {		/* Defer initialization to selinux_complete_init. */		return 0;	}	down(&isec->sem);	isec->sclass = inode_mode_to_security_class(inode->i_mode);	isec->sid = sid;	isec->initialized = 1;	up(&isec->sem);	return 0;}/* Set the security attributes on a newly created file. */static int post_create(struct inode *dir,		       struct dentry *dentry){	struct task_security_struct *tsec;	struct inode *inode;	struct inode_security_struct *dsec;	struct superblock_security_struct *sbsec;	u32 newsid;	char *context;	unsigned int len;	int rc;	tsec = current->security;	dsec = dir->i_security;	sbsec = dir->i_sb->s_security;	inode = dentry->d_inode;	if (!inode) {		/* Some file system types (e.g. NFS) may not instantiate		   a dentry for all create operations (e.g. symlink),		   so we have to check to see if the inode is non-NULL. */		printk(KERN_WARNING "post_create:  no inode, dir (dev=%s, "		       "ino=%ld)\n", dir->i_sb->s_id, dir->i_ino);		return 0;	}	if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {		newsid = tsec->create_sid;	} else {		rc = security_transition_sid(tsec->sid, dsec->sid,					     inode_mode_to_security_class(inode->i_mode),					     &newsid);		if (rc) {			printk(KERN_WARNING "post_create:  "			       "security_transition_sid failed, rc=%d (dev=%s "			       "ino=%ld)\n",			       -rc, inode->i_sb->s_id, inode->i_ino);			return rc;		}	}	rc = inode_security_set_sid(inode, newsid);	if (rc) {		printk(KERN_WARNING "post_create:  inode_security_set_sid "		       "failed, rc=%d (dev=%s ino=%ld)\n",		       -rc, inode->i_sb->s_id, inode->i_ino);		return rc;	}	if (sbsec->behavior == SECURITY_FS_USE_XATTR &&	    inode->i_op->setxattr) {		/* Use extended attributes. */		rc = security_sid_to_context(newsid, &context, &len);		if (rc) {			printk(KERN_WARNING "post_create:  sid_to_context "			       "failed, rc=%d (dev=%s ino=%ld)\n",			       -rc, inode->i_sb->s_id, inode->i_ino);			return rc;		}		down(&inode->i_sem);		rc = inode->i_op->setxattr(dentry,					   XATTR_NAME_SELINUX,					   context, len, 0);		up(&inode->i_sem);		kfree(context);		if (rc < 0) {			printk(KERN_WARNING "post_create:  setxattr failed, "			       "rc=%d (dev=%s ino=%ld)\n",			       -rc, inode->i_sb->s_id, inode->i_ino);			return rc;		}	}	return 0;}/* Hook functions begin here. */static int selinux_ptrace(struct task_struct *parent, struct task_struct *child){	struct task_security_struct *psec = parent->security;	struct task_security_struct *csec = child->security;	int rc;	rc = secondary_ops->ptrace(parent,child);	if (rc)		return rc;	rc = task_has_perm(parent, child, PROCESS__PTRACE);	/* Save the SID of the tracing process for later use in apply_creds. */	if (!rc)		csec->ptrace_sid = psec->sid;	return rc;}static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,                          kernel_cap_t *inheritable, kernel_cap_t *permitted){	int error;	error = task_has_perm(current, target, PROCESS__GETCAP);	if (error)		return error;	return secondary_ops->capget(target, effective, inheritable, permitted);}static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective,                                kernel_cap_t *inheritable, kernel_cap_t *permitted){	int error;	error = secondary_ops->capset_check(target, effective, inheritable, permitted);	if (error)		return error;	return task_has_perm(current, target, PROCESS__SETCAP);}static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective,                               kernel_cap_t *inheritable, kernel_cap_t *permitted){	int error;	error = task_has_perm(current, target, PROCESS__SETCAP);	if (error)		return;	secondary_ops->capset_set(target, effective, inheritable, permitted);}static int selinux_capable(struct task_struct *tsk, int cap){	int rc;	rc = secondary_ops->capable(tsk, cap);	if (rc)		return rc;	return task_has_capability(tsk,cap);}static int selinux_sysctl(ctl_table *table, int op){	int error = 0;	u32 av;	struct task_security_struct *tsec;	u32 tsid;	int rc;	rc = secondary_ops->sysctl(table, op);	if (rc)		return rc;	tsec = current->security;	rc = selinux_proc_get_sid(table->de, (op == 001) ?	                          SECCLASS_DIR : SECCLASS_FILE, &tsid);	if (rc) {		/* Default to the well-defined sysctl SID. */		tsid = SECINITSID_SYSCTL;	}	/* The op values are "defined" in sysctl.c, thereby creating	 * a bad coupling between this module and sysctl.c */	if(op == 001) {		error = avc_has_perm(tsec->sid, tsid,				     SECCLASS_DIR, DIR__SEARCH, NULL, NULL);	} else {		av = 0;		if (op & 004)			av |= FILE__READ;		if (op & 002)			av |= FILE__WRITE;		if (av)			error = avc_has_perm(tsec->sid, tsid,					     SECCLASS_FILE, av, NULL, NULL);        }	return error;}static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb){	int rc = 0;	if (!sb)		return 0;	switch (cmds) {		case Q_SYNC:		case Q_QUOTAON:		case Q_QUOTAOFF:	        case Q_SETINFO:		case Q_SETQUOTA:			rc = superblock_has_perm(current,						 sb,						 FILESYSTEM__QUOTAMOD, NULL);			break;	        case Q_GETFMT:	        case Q_GETINFO:		case Q_GETQUOTA:			rc = superblock_has_perm(current,						 sb,						 FILESYSTEM__QUOTAGET, NULL);			break;		default:			rc = 0;  /* let the kernel handle invalid cmds */			break;	}	return rc;}static int selinux_quota_on(struct file *f){	return file_has_perm(current, f, FILE__QUOTAON);}static int selinux_syslog(int type){	int rc;	rc = secondary_ops->syslog(type);	if (rc)		return rc;	switch (type) {		case 3:         /* Read last kernel messages */		case 10:        /* Return size of the log buffer */			rc = task_has_system(current, SYSTEM__SYSLOG_READ);			break;		case 6:         /* Disable logging to console */		case 7:         /* Enable logging to console */		case 8:		/* Set level of messages printed to console */			rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);			break;		case 0:         /* Close log */		case 1:         /* Open log */		case 2:         /* Read from log */		case 4:         /* Read/clear last kernel messages */		case 5:         /* Clear ring buffer */		default:			rc = task_has_system(current, SYSTEM__SYSLOG_MOD);			break;	}	return rc;}/* * Check that a process has enough memory to allocate a new virtual * mapping. 0 means there is enough memory for the allocation to * succeed and -ENOMEM implies there is not. * * We currently support three overcommit policies, which are set via the * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting * * Strict overcommit modes added 2002 Feb 26 by Alan Cox. * Additional code 2002 Jul 20 by Robert Love. */static int selinux_vm_enough_memory(long pages){	unsigned long free, allowed;	int rc;	struct task_security_struct *tsec = current->security;	vm_acct_memory(pages);        /*	 * Sometimes we want to use more memory than we have	 */	if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)		return 0;	if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {		free = get_page_cache_size();		free += nr_free_pages();		free += nr_swap_pages;		/*		 * Any slabs which are created with the		 * SLAB_RECLAIM_ACCOUNT flag claim to have contents		 * which are reclaimable, under pressure.  The dentry		 * cache and most inode caches should fall into this		 */		free += atomic_read(&slab_reclaim_pages);		/*		 * Leave the last 3% for privileged processes.		 * Don't audit the check, as it is applied to all processes		 * that allocate mappings.		 */		rc = secondary_ops->capable(current, CAP_SYS_ADMIN);		if (!rc) {			rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,						  SECCLASS_CAPABILITY,						  CAP_TO_MASK(CAP_SYS_ADMIN),						  NULL, NULL);		}		if (rc)			free -= free / 32;		if (free > pages)			return 0;		vm_unacct_memory(pages);		return -ENOMEM;	}	allowed = (totalram_pages - hugetlb_total_pages())		* sysctl_overcommit_ratio / 100;	allowed += total_swap_pages;	if (atomic_read(&vm_committed_space) < allowed)		return 0;	vm_unacct_memory(pages);	return -ENOMEM;}

⌨️ 快捷键说明

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