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

📄 hooks.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* binprm security operations */static int selinux_bprm_alloc_security(struct linux_binprm *bprm){	struct bprm_security_struct *bsec;	bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);	if (!bsec)		return -ENOMEM;	bsec->bprm = bprm;	bsec->sid = SECINITSID_UNLABELED;	bsec->set = 0;	bprm->security = bsec;	return 0;}static int selinux_bprm_set_security(struct linux_binprm *bprm){	struct task_security_struct *tsec;	struct inode *inode = bprm->file->f_path.dentry->d_inode;	struct inode_security_struct *isec;	struct bprm_security_struct *bsec;	u32 newsid;	struct avc_audit_data ad;	int rc;	rc = secondary_ops->bprm_set_security(bprm);	if (rc)		return rc;	bsec = bprm->security;	if (bsec->set)		return 0;	tsec = current->security;	isec = inode->i_security;	/* Default to the current task SID. */	bsec->sid = tsec->sid;	/* Reset fs, key, and sock SIDs on execve. */	tsec->create_sid = 0;	tsec->keycreate_sid = 0;	tsec->sockcreate_sid = 0;	if (tsec->exec_sid) {		newsid = tsec->exec_sid;		/* Reset exec SID on execve. */		tsec->exec_sid = 0;	} else {		/* Check for a default transition on this program. */		rc = security_transition_sid(tsec->sid, isec->sid,		                             SECCLASS_PROCESS, &newsid);		if (rc)			return rc;	}	AVC_AUDIT_DATA_INIT(&ad, FS);	ad.u.fs.mnt = bprm->file->f_path.mnt;	ad.u.fs.dentry = bprm->file->f_path.dentry;	if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)		newsid = tsec->sid;        if (tsec->sid == newsid) {		rc = avc_has_perm(tsec->sid, isec->sid,				  SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);		if (rc)			return rc;	} else {		/* Check permissions for the transition. */		rc = avc_has_perm(tsec->sid, newsid,				  SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);		if (rc)			return rc;		rc = avc_has_perm(newsid, isec->sid,				  SECCLASS_FILE, FILE__ENTRYPOINT, &ad);		if (rc)			return rc;		/* Clear any possibly unsafe personality bits on exec: */		current->personality &= ~PER_CLEAR_ON_SETID;		/* Set the security field to the new SID. */		bsec->sid = newsid;	}	bsec->set = 1;	return 0;}static int selinux_bprm_check_security (struct linux_binprm *bprm){	return secondary_ops->bprm_check_security(bprm);}static int selinux_bprm_secureexec (struct linux_binprm *bprm){	struct task_security_struct *tsec = current->security;	int atsecure = 0;	if (tsec->osid != tsec->sid) {		/* Enable secure mode for SIDs transitions unless		   the noatsecure permission is granted between		   the two SIDs, i.e. ahp returns 0. */		atsecure = avc_has_perm(tsec->osid, tsec->sid,					 SECCLASS_PROCESS,					 PROCESS__NOATSECURE, NULL);	}	return (atsecure || secondary_ops->bprm_secureexec(bprm));}static void selinux_bprm_free_security(struct linux_binprm *bprm){	kfree(bprm->security);	bprm->security = NULL;}extern struct vfsmount *selinuxfs_mount;extern struct dentry *selinux_null;/* Derived from fs/exec.c:flush_old_files. */static inline void flush_unauthorized_files(struct files_struct * files){	struct avc_audit_data ad;	struct file *file, *devnull = NULL;	struct tty_struct *tty;	struct fdtable *fdt;	long j = -1;	int drop_tty = 0;	mutex_lock(&tty_mutex);	tty = get_current_tty();	if (tty) {		file_list_lock();		file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);		if (file) {			/* Revalidate access to controlling tty.			   Use inode_has_perm on the tty inode directly rather			   than using file_has_perm, as this particular open			   file may belong to another process and we are only			   interested in the inode-based check here. */			struct inode *inode = file->f_path.dentry->d_inode;			if (inode_has_perm(current, inode,					   FILE__READ | FILE__WRITE, NULL)) {				drop_tty = 1;			}		}		file_list_unlock();	}	mutex_unlock(&tty_mutex);	/* Reset controlling tty. */	if (drop_tty)		no_tty();	/* Revalidate access to inherited open files. */	AVC_AUDIT_DATA_INIT(&ad,FS);	spin_lock(&files->file_lock);	for (;;) {		unsigned long set, i;		int fd;		j++;		i = j * __NFDBITS;		fdt = files_fdtable(files);		if (i >= fdt->max_fds)			break;		set = fdt->open_fds->fds_bits[j];		if (!set)			continue;		spin_unlock(&files->file_lock);		for ( ; set ; i++,set >>= 1) {			if (set & 1) {				file = fget(i);				if (!file)					continue;				if (file_has_perm(current,						  file,						  file_to_av(file))) {					sys_close(i);					fd = get_unused_fd();					if (fd != i) {						if (fd >= 0)							put_unused_fd(fd);						fput(file);						continue;					}					if (devnull) {						get_file(devnull);					} else {						devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);						if (IS_ERR(devnull)) {							devnull = NULL;							put_unused_fd(fd);							fput(file);							continue;						}					}					fd_install(fd, devnull);				}				fput(file);			}		}		spin_lock(&files->file_lock);	}	spin_unlock(&files->file_lock);}static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe){	struct task_security_struct *tsec;	struct bprm_security_struct *bsec;	u32 sid;	int rc;	secondary_ops->bprm_apply_creds(bprm, unsafe);	tsec = current->security;	bsec = bprm->security;	sid = bsec->sid;	tsec->osid = tsec->sid;	bsec->unsafe = 0;	if (tsec->sid != sid) {		/* Check for shared state.  If not ok, leave SID		   unchanged and kill. */		if (unsafe & LSM_UNSAFE_SHARE) {			rc = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,					PROCESS__SHARE, NULL);			if (rc) {				bsec->unsafe = 1;				return;			}		}		/* Check for ptracing, and update the task SID if ok.		   Otherwise, leave SID unchanged and kill. */		if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {			rc = avc_has_perm(tsec->ptrace_sid, sid,					  SECCLASS_PROCESS, PROCESS__PTRACE,					  NULL);			if (rc) {				bsec->unsafe = 1;				return;			}		}		tsec->sid = sid;	}}/* * called after apply_creds without the task lock held */static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm){	struct task_security_struct *tsec;	struct rlimit *rlim, *initrlim;	struct itimerval itimer;	struct bprm_security_struct *bsec;	int rc, i;	tsec = current->security;	bsec = bprm->security;	if (bsec->unsafe) {		force_sig_specific(SIGKILL, current);		return;	}	if (tsec->osid == tsec->sid)		return;	/* Close files for which the new task SID is not authorized. */	flush_unauthorized_files(current->files);	/* Check whether the new SID can inherit signal state	   from the old SID.  If not, clear itimers to avoid	   subsequent signal generation and flush and unblock	   signals. This must occur _after_ the task SID has	  been updated so that any kill done after the flush	  will be checked against the new SID. */	rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,			  PROCESS__SIGINH, NULL);	if (rc) {		memset(&itimer, 0, sizeof itimer);		for (i = 0; i < 3; i++)			do_setitimer(i, &itimer, NULL);		flush_signals(current);		spin_lock_irq(&current->sighand->siglock);		flush_signal_handlers(current, 1);		sigemptyset(&current->blocked);		recalc_sigpending();		spin_unlock_irq(&current->sighand->siglock);	}	/* Always clear parent death signal on SID transitions. */	current->pdeath_signal = 0;	/* Check whether the new SID can inherit resource limits	   from the old SID.  If not, reset all soft limits to	   the lower of the current task's hard limit and the init	   task's soft limit.  Note that the setting of hard limits	   (even to lower them) can be controlled by the setrlimit	   check. The inclusion of the init task's soft limit into	   the computation is to avoid resetting soft limits higher	   than the default soft limit for cases where the default	   is lower than the hard limit, e.g. RLIMIT_CORE or	   RLIMIT_STACK.*/	rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,			  PROCESS__RLIMITINH, NULL);	if (rc) {		for (i = 0; i < RLIM_NLIMITS; i++) {			rlim = current->signal->rlim + i;			initrlim = init_task.signal->rlim+i;			rlim->rlim_cur = min(rlim->rlim_max,initrlim->rlim_cur);		}		if (current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {			/*			 * This will cause RLIMIT_CPU calculations			 * to be refigured.			 */			current->it_prof_expires = jiffies_to_cputime(1);		}	}	/* Wake up the parent if it is waiting so that it can	   recheck wait permission to the new task SID. */	wake_up_interruptible(&current->parent->signal->wait_chldexit);}/* superblock security operations */static int selinux_sb_alloc_security(struct super_block *sb){	return superblock_alloc_security(sb);}static void selinux_sb_free_security(struct super_block *sb){	superblock_free_security(sb);}static inline int match_prefix(char *prefix, int plen, char *option, int olen){	if (plen > olen)		return 0;	return !memcmp(prefix, option, plen);}static inline int selinux_option(char *option, int len){	return (match_prefix("context=", sizeof("context=")-1, option, len) ||	        match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) ||	        match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) ||		match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len));}static inline void take_option(char **to, char *from, int *first, int len){	if (!*first) {		**to = ',';		*to += 1;	} else		*first = 0;	memcpy(*to, from, len);	*to += len;}static inline void take_selinux_option(char **to, char *from, int *first, 		                       int len){	int current_size = 0;	if (!*first) {		**to = '|';		*to += 1;	}	else		*first = 0;	while (current_size < len) {		if (*from != '"') {			**to = *from;			*to += 1;		}		from += 1;		current_size += 1;	}}static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy){	int fnosec, fsec, rc = 0;	char *in_save, *in_curr, *in_end;	char *sec_curr, *nosec_save, *nosec;	int open_quote = 0;	in_curr = orig;	sec_curr = copy;	/* Binary mount data: just copy */	if (type->fs_flags & FS_BINARY_MOUNTDATA) {		copy_page(sec_curr, in_curr);		goto out;	}	nosec = (char *)get_zeroed_page(GFP_KERNEL);	if (!nosec) {		rc = -ENOMEM;		goto out;	}	nosec_save = nosec;	fnosec = fsec = 1;	in_save = in_end = orig;	do {		if (*in_end == '"')			open_quote = !open_quote;		if ((*in_end == ',' && open_quote == 0) ||				*in_end == '\0') {			int len = in_end - in_curr;			if (selinux_option(in_curr, len))				take_selinux_option(&sec_curr, in_curr, &fsec, len);			else				take_option(&nosec, in_curr, &fnosec, len);			in_curr = in_end + 1;		}	} while (*in_end++);	strcpy(in_save, nosec_save);	free_page((unsigned long)nosec_save);out:	return rc;}static int selinux_sb_kern_mount(struct super_block *sb, void *data){	struct avc_audit_data ad;	int rc;	rc = superblock_doinit(sb, data);	if (rc)		return rc;	AVC_AUDIT_DATA_INIT(&ad,FS);	ad.u.fs.dentry = sb->s_root;	return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad);}static int selinux_sb_statfs(struct dentry *dentry){	struct avc_audit_data ad;	AVC_AUDIT_DATA_INIT(&ad,FS);	ad.u.fs.dentry = dentry->d_sb->s_root;	return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad);}static int selinux_mount(char * dev_name,                         struct nameidata *nd,                         char * type,                         unsigned long flags,                         void * data){	int rc;	rc = secondary_ops->sb_mount(dev_name, nd, type, flags, data);	if (rc)		return rc;	if (flags & MS_REMOUNT)		return superblock_has_perm(current, nd->mnt->mnt_sb,		                           FILESYSTEM__REMOUNT, NULL);	else		return dentry_has_perm(current, nd->mnt, nd->dentry,		                       FILE__MOUNTON);}static int selinux_umount(struct vfsmount *mnt, int flags){	int rc;	rc = secondary_ops->sb_umount(mnt, flags);	if (rc)		return rc;	return superblock_has_perm(current,mnt->mnt_sb,	                           FILESYSTEM__UNMOUNT,NULL);}/* inode security operations */static int selinux_inode_alloc_security(struct inode *inode){	return inode_alloc_security(inode);}static void selinux_inode_free_security(struct inode *inode){	inode_free_security(inode);}static int selinux_inode_init_security(struct inode *inode, struct inode *dir,				       char **name, void **value,				       size_t *len){	struct task_security_struct *tsec;	struct inode_security_struct *dsec;	struct superblock_security_struct *sbsec;	u32 newsid, clen;	int rc;	char *namep = NULL, *context;	tsec = current->security;	dsec = dir->i_security;	sbsec = dir->i_sb->s_security;	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),

⌨️ 快捷键说明

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