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

📄 hooks.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
/* binprm security operations */static int selinux_bprm_alloc_security(struct linux_binprm *bprm){	struct bprm_security_struct *bsec;	bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);	if (!bsec)		return -ENOMEM;	memset(bsec, 0, sizeof *bsec);	bsec->magic = SELINUX_MAGIC;	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_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 create SID on execve. */	tsec->create_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_vfsmnt;	ad.u.fs.dentry = bprm->file->f_dentry;	if (bprm->file->f_vfsmnt->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,				  &isec->avcr, &ad);		if (rc)			return rc;	} else {		/* Check permissions for the transition. */		rc = avc_has_perm(tsec->sid, newsid,				  SECCLASS_PROCESS, PROCESS__TRANSITION,				  NULL,				  &ad);		if (rc)			return rc;		rc = avc_has_perm(newsid, isec->sid,				  SECCLASS_FILE, FILE__ENTRYPOINT,				  &isec->avcr, &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, NULL);	}	return (atsecure || secondary_ops->bprm_secureexec(bprm));}static void selinux_bprm_free_security(struct linux_binprm *bprm){	struct bprm_security_struct *bsec = bprm->security;	bprm->security = NULL;	kfree(bsec);}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 = current->signal->tty;	long j = -1;	if (tty) {		file_list_lock();		file = list_entry(tty->tty_files.next, typeof(*file), f_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_dentry->d_inode;			if (inode_has_perm(current, inode,					   FILE__READ | FILE__WRITE,					   NULL, NULL)) {				/* Reset controlling tty. */				current->signal->tty = NULL;				current->signal->tty_old_pgrp = 0;			}		}		file_list_unlock();	}	/* 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;		if (i >= files->max_fds || i >= files->max_fdset)			break;		set = files->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) {						atomic_inc(&devnull->f_count);					} else {						devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);						if (!devnull) {							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;	struct av_decision avd;	struct itimerval itimer;	struct rlimit *rlim, *initrlim;	int rc, i;	secondary_ops->bprm_apply_creds(bprm, unsafe);	tsec = current->security;	bsec = bprm->security;	sid = bsec->sid;	tsec->osid = tsec->sid;	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_noaudit(tsec->sid, sid,					  SECCLASS_PROCESS, PROCESS__SHARE,					  NULL, &avd);			if (rc) {				task_unlock(current);				avc_audit(tsec->sid, sid, SECCLASS_PROCESS,				    PROCESS__SHARE, &avd, rc, NULL);				force_sig_specific(SIGKILL, current);				goto lock_out;			}		}		/* 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_noaudit(tsec->ptrace_sid, sid,					  SECCLASS_PROCESS, PROCESS__PTRACE,					  NULL, &avd);			if (!rc)				tsec->sid = sid;			task_unlock(current);			avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS,				  PROCESS__PTRACE, &avd, rc, NULL);			if (rc) {				force_sig_specific(SIGKILL, current);				goto lock_out;			}		} else {			tsec->sid = sid;			task_unlock(current);		}		/* 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, 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);		}		/* 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, NULL);		if (rc) {			for (i = 0; i < RLIM_NLIMITS; i++) {				rlim = current->rlim + i;				initrlim = init_task.rlim+i;				rlim->rlim_cur = min(rlim->rlim_max,initrlim->rlim_cur);			}		}		/* 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->wait_chldexit);lock_out:		task_lock(current);		return;	}}/* 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));}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 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;	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 == ',' || *in_end == '\0') {			int len = in_end - in_curr;			if (selinux_option(in_curr, len))				take_option(&sec_curr, in_curr, &fsec, len);			else				take_option(&nosec, in_curr, &fnosec, len);			in_curr = in_end + 1;		}	} while (*in_end++);	copy_page(in_save, 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 super_block *sb){	struct avc_audit_data ad;	AVC_AUDIT_DATA_INIT(&ad,FS);	ad.u.fs.dentry = sb->s_root;	return superblock_has_perm(current, 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_create(struct inode *dir, struct dentry *dentry, int mask){	return may_create(dir, dentry, SECCLASS_FILE);}static void selinux_inode_post_create(struct inode *dir, struct dentry *dentry, int mask){	post_create(dir, dentry);}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 void selinux_inode_post_link(struct dentry *old_dentry, struct inode *inode, struct dentry *new_dentry){	return;}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 void selinux_inode_post_symlink(struct inode *dir, struct dentry *dentry, const char *name){	post_create(dir, dentry);}static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask){	return may_create(dir, dentry, SECCLASS_DIR);}static void selinux_inode_post_mkdir(struct inode *dir, struct dentry *dentry, int mask){	post_create(dir, dentry);}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;

⌨️ 快捷键说明

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