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

📄 hooks.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
					     &newsid);		if (rc) {			printk(KERN_WARNING "%s:  "			       "security_transition_sid failed, rc=%d (dev=%s "			       "ino=%ld)\n",			       __FUNCTION__,			       -rc, inode->i_sb->s_id, inode->i_ino);			return rc;		}	}	/* Possibly defer initialization to selinux_complete_init. */	if (sbsec->initialized) {		struct inode_security_struct *isec = inode->i_security;		isec->sclass = inode_mode_to_security_class(inode->i_mode);		isec->sid = newsid;		isec->initialized = 1;	}	if (!ss_initialized || sbsec->behavior == SECURITY_FS_USE_MNTPOINT)		return -EOPNOTSUPP;	if (name) {		namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);		if (!namep)			return -ENOMEM;		*name = namep;	}	if (value && len) {		rc = security_sid_to_context(newsid, &context, &clen);		if (rc) {			kfree(namep);			return rc;		}		*value = context;		*len = clen;	}	return 0;}static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask){	return may_create(dir, dentry, SECCLASS_FILE);}static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry){	int rc;	rc = secondary_ops->inode_link(old_dentry,dir,new_dentry);	if (rc)		return rc;	return may_link(dir, old_dentry, MAY_LINK);}static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry){	int rc;	rc = secondary_ops->inode_unlink(dir, dentry);	if (rc)		return rc;	return may_link(dir, dentry, MAY_UNLINK);}static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name){	return may_create(dir, dentry, SECCLASS_LNK_FILE);}static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask){	return may_create(dir, dentry, SECCLASS_DIR);}static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry){	return may_link(dir, dentry, MAY_RMDIR);}static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev){	int rc;	rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);	if (rc)		return rc;	return may_create(dir, dentry, inode_mode_to_security_class(mode));}static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,                                struct inode *new_inode, struct dentry *new_dentry){	return may_rename(old_inode, old_dentry, new_inode, new_dentry);}static int selinux_inode_readlink(struct dentry *dentry){	return dentry_has_perm(current, NULL, dentry, FILE__READ);}static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata){	int rc;	rc = secondary_ops->inode_follow_link(dentry,nameidata);	if (rc)		return rc;	return dentry_has_perm(current, NULL, dentry, FILE__READ);}static int selinux_inode_permission(struct inode *inode, int mask,				    struct nameidata *nd){	int rc;	rc = secondary_ops->inode_permission(inode, mask, nd);	if (rc)		return rc;	if (!mask) {		/* No permission to check.  Existence test. */		return 0;	}	return inode_has_perm(current, inode,			       file_mask_to_av(inode->i_mode, mask), NULL);}static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr){	int rc;	rc = secondary_ops->inode_setattr(dentry, iattr);	if (rc)		return rc;	if (iattr->ia_valid & ATTR_FORCE)		return 0;	if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |			       ATTR_ATIME_SET | ATTR_MTIME_SET))		return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);	return dentry_has_perm(current, NULL, dentry, FILE__WRITE);}static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry){	return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);}static int selinux_inode_setotherxattr(struct dentry *dentry, char *name){	if (!strncmp(name, XATTR_SECURITY_PREFIX,		     sizeof XATTR_SECURITY_PREFIX - 1)) {		if (!strcmp(name, XATTR_NAME_CAPS)) {			if (!capable(CAP_SETFCAP))				return -EPERM;		} else if (!capable(CAP_SYS_ADMIN)) {			/* A different attribute in the security namespace.			   Restrict to administrator. */			return -EPERM;		}	}	/* Not an attribute we recognize, so just check the	   ordinary setattr permission. */	return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);}static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags){	struct task_security_struct *tsec = current->security;	struct inode *inode = dentry->d_inode;	struct inode_security_struct *isec = inode->i_security;	struct superblock_security_struct *sbsec;	struct avc_audit_data ad;	u32 newsid;	int rc = 0;	if (strcmp(name, XATTR_NAME_SELINUX))		return selinux_inode_setotherxattr(dentry, name);	sbsec = inode->i_sb->s_security;	if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)		return -EOPNOTSUPP;	if (!is_owner_or_cap(inode))		return -EPERM;	AVC_AUDIT_DATA_INIT(&ad,FS);	ad.u.fs.dentry = dentry;	rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass,			  FILE__RELABELFROM, &ad);	if (rc)		return rc;	rc = security_context_to_sid(value, size, &newsid);	if (rc)		return rc;	rc = avc_has_perm(tsec->sid, newsid, isec->sclass,			  FILE__RELABELTO, &ad);	if (rc)		return rc;	rc = security_validate_transition(isec->sid, newsid, tsec->sid,	                                  isec->sclass);	if (rc)		return rc;	return avc_has_perm(newsid,			    sbsec->sid,			    SECCLASS_FILESYSTEM,			    FILESYSTEM__ASSOCIATE,			    &ad);}static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,                                        void *value, size_t size, int flags){	struct inode *inode = dentry->d_inode;	struct inode_security_struct *isec = inode->i_security;	u32 newsid;	int rc;	if (strcmp(name, XATTR_NAME_SELINUX)) {		/* Not an attribute we recognize, so nothing to do. */		return;	}	rc = security_context_to_sid(value, size, &newsid);	if (rc) {		printk(KERN_WARNING "%s:  unable to obtain SID for context "		       "%s, rc=%d\n", __FUNCTION__, (char*)value, -rc);		return;	}	isec->sid = newsid;	return;}static int selinux_inode_getxattr (struct dentry *dentry, char *name){	return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);}static int selinux_inode_listxattr (struct dentry *dentry){	return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);}static int selinux_inode_removexattr (struct dentry *dentry, char *name){	if (strcmp(name, XATTR_NAME_SELINUX))		return selinux_inode_setotherxattr(dentry, name);	/* No one is allowed to remove a SELinux security label.	   You can change the label, but all data must be labeled. */	return -EACCES;}/* * Copy the in-core inode security context value to the user.  If the * getxattr() prior to this succeeded, check to see if we need to * canonicalize the value to be finally returned to the user. * * Permission check is handled by selinux_inode_getxattr hook. */static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err){	struct inode_security_struct *isec = inode->i_security;	if (strcmp(name, XATTR_SELINUX_SUFFIX))		return -EOPNOTSUPP;	return selinux_getsecurity(isec->sid, buffer, size);}static int selinux_inode_setsecurity(struct inode *inode, const char *name,                                     const void *value, size_t size, int flags){	struct inode_security_struct *isec = inode->i_security;	u32 newsid;	int rc;	if (strcmp(name, XATTR_SELINUX_SUFFIX))		return -EOPNOTSUPP;	if (!value || !size)		return -EACCES;	rc = security_context_to_sid((void*)value, size, &newsid);	if (rc)		return rc;	isec->sid = newsid;	return 0;}static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size){	const int len = sizeof(XATTR_NAME_SELINUX);	if (buffer && len <= buffer_size)		memcpy(buffer, XATTR_NAME_SELINUX, len);	return len;}static int selinux_inode_need_killpriv(struct dentry *dentry){	return secondary_ops->inode_need_killpriv(dentry);}static int selinux_inode_killpriv(struct dentry *dentry){	return secondary_ops->inode_killpriv(dentry);}/* file security operations */static int selinux_revalidate_file_permission(struct file *file, int mask){	int rc;	struct inode *inode = file->f_path.dentry->d_inode;	if (!mask) {		/* No permission to check.  Existence test. */		return 0;	}	/* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */	if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))		mask |= MAY_APPEND;	rc = file_has_perm(current, file,			   file_mask_to_av(inode->i_mode, mask));	if (rc)		return rc;	return selinux_netlbl_inode_permission(inode, mask);}static int selinux_file_permission(struct file *file, int mask){	struct inode *inode = file->f_path.dentry->d_inode;	struct task_security_struct *tsec = current->security;	struct file_security_struct *fsec = file->f_security;	struct inode_security_struct *isec = inode->i_security;	if (!mask) {		/* No permission to check.  Existence test. */		return 0;	}	if (tsec->sid == fsec->sid && fsec->isid == isec->sid	    && fsec->pseqno == avc_policy_seqno())		return selinux_netlbl_inode_permission(inode, mask);	return selinux_revalidate_file_permission(file, mask);}static int selinux_file_alloc_security(struct file *file){	return file_alloc_security(file);}static void selinux_file_free_security(struct file *file){	file_free_security(file);}static int selinux_file_ioctl(struct file *file, unsigned int cmd,			      unsigned long arg){	int error = 0;	switch (cmd) {		case FIONREAD:		/* fall through */		case FIBMAP:		/* fall through */		case FIGETBSZ:		/* fall through */		case EXT2_IOC_GETFLAGS:		/* fall through */		case EXT2_IOC_GETVERSION:			error = file_has_perm(current, file, FILE__GETATTR);			break;		case EXT2_IOC_SETFLAGS:		/* fall through */		case EXT2_IOC_SETVERSION:			error = file_has_perm(current, file, FILE__SETATTR);			break;		/* sys_ioctl() checks */		case FIONBIO:		/* fall through */		case FIOASYNC:			error = file_has_perm(current, file, 0);			break;	        case KDSKBENT:	        case KDSKBSENT:			error = task_has_capability(current,CAP_SYS_TTY_CONFIG);			break;		/* default case assumes that the command will go		 * to the file's ioctl() function.		 */		default:			error = file_has_perm(current, file, FILE__IOCTL);	}	return error;}static int file_map_prot_check(struct file *file, unsigned long prot, int shared){#ifndef CONFIG_PPC32	if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {		/*		 * We are making executable an anonymous mapping or a		 * private file mapping that will also be writable.		 * This has an additional check.		 */		int rc = task_has_perm(current, current, PROCESS__EXECMEM);		if (rc)			return rc;	}#endif	if (file) {		/* read access is always possible with a mapping */		u32 av = FILE__READ;		/* write access only matters if the mapping is shared */		if (shared && (prot & PROT_WRITE))			av |= FILE__WRITE;		if (prot & PROT_EXEC)			av |= FILE__EXECUTE;		return file_has_perm(current, file, av);	}	return 0;}static int selinux_file_mmap(struct file *file, unsigned long reqprot,			     unsigned long prot, unsigned long flags,			     unsigned long addr, unsigned long addr_only){	int rc = 0;	u32 sid = ((struct task_security_struct*)(current->security))->sid;	if (addr < mmap_min_addr)		rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,				  MEMPROTECT__MMAP_ZERO, NULL);	if (rc || addr_only)		return rc;	if (selinux_checkreqprot)		prot = reqprot;	return file_map_prot_check(file, prot,				   (flags & MAP_TYPE) == MAP_SHARED);}static int selinux_file_mprotect(struct vm_area_struct *vma,				 unsigned long reqprot,				 unsigned long prot){	int rc;	rc = secondary_ops->file_mprotect(vma, reqprot, prot);	if (rc)		return rc;	if (selinux_checkreqprot)		prot = reqprot;#ifndef CONFIG_PPC32	if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {		rc = 0;		if (vma->vm_start >= vma->vm_mm->start_brk &&		    vma->vm_end <= vma->vm_mm->brk) {			rc = task_has_perm(current, current,					   PROCESS__EXECHEAP);		} else if (!vma->vm_file &&			   vma->vm_start <= vma->vm_mm->start_stack &&			   vma->vm_end >= vma->vm_mm->start_stack) {			rc = task_has_perm(current, current, PROCESS__EXECSTACK);		} else if (vma->vm_file && vma->anon_vma) {			/*			 * We are making executable a file mapping that has			 * had some COW done. Since pages might have been			 * written, check ability to execute the possibly			 * modified content.  This typically should only			 * occur for text relocations.			 */			rc = file_has_perm(current, vma->vm_file,					   FILE__EXECMOD);		}		if (rc)			return rc;	}#endif	return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);}static int selinux_file_lock(struct file *file, unsigned int cmd){	return file_has_perm(current, file, FILE__LOCK);}static int selinux_file_fcntl(struct file *file, unsigned int cmd,			      unsigned long arg){	int err = 0;	switch (cmd) {	        case F_SETFL:			if (!file->f_path.dentry || !file->f_path.dentry->d_inode) {				err = -EINVAL;				break;			}			if ((file->f_

⌨️ 快捷键说明

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