diff options
| author | James Morris <jmorris@namei.org> | 2011-05-24 23:20:19 +1000 | 
|---|---|---|
| committer | James Morris <jmorris@namei.org> | 2011-05-24 23:20:19 +1000 | 
| commit | b7b57551bbda1390959207f79f2038aa7adb72ae (patch) | |
| tree | d591a08e7e45615b51d8b5ee1634a29920f62c3f /security/selinux/hooks.c | |
| parent | 434d42cfd05a7cc452457a81d2029540cba12150 (diff) | |
| parent | 7a627e3b9a2bd0f06945bbe64bcf403e788ecf6e (diff) | |
| download | olio-linux-3.10-b7b57551bbda1390959207f79f2038aa7adb72ae.tar.xz olio-linux-3.10-b7b57551bbda1390959207f79f2038aa7adb72ae.zip  | |
Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into for-linus
Conflicts:
	lib/flex_array.c
	security/selinux/avc.c
	security/selinux/hooks.c
	security/selinux/ss/policydb.c
	security/smack/smack_lsm.c
Manually resolve conflicts.
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 92 | 
1 files changed, 55 insertions, 37 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 8fb24884300..a0d38459d65 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -990,6 +990,7 @@ static void selinux_write_opts(struct seq_file *m,  			continue;  		default:  			BUG(); +			return;  		};  		/* we need a comma before each option */  		seq_putc(m, ','); @@ -1443,6 +1444,7 @@ static int task_has_capability(struct task_struct *tsk,  		printk(KERN_ERR  		       "SELinux:  out of range capability %d\n", cap);  		BUG(); +		return -EINVAL;  	}  	rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); @@ -1487,8 +1489,8 @@ static int inode_has_perm(const struct cred *cred,  	if (!adp) {  		adp = &ad; -		COMMON_AUDIT_DATA_INIT(&ad, FS); -		ad.u.fs.inode = inode; +		COMMON_AUDIT_DATA_INIT(&ad, INODE); +		ad.u.inode = inode;  	}  	return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); @@ -1498,16 +1500,29 @@ static int inode_has_perm(const struct cred *cred,     the dentry to help the auditing code to more easily generate the     pathname if needed. */  static inline int dentry_has_perm(const struct cred *cred, -				  struct vfsmount *mnt,  				  struct dentry *dentry,  				  u32 av)  {  	struct inode *inode = dentry->d_inode;  	struct common_audit_data ad; -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.path.mnt = mnt; -	ad.u.fs.path.dentry = dentry; +	COMMON_AUDIT_DATA_INIT(&ad, DENTRY); +	ad.u.dentry = dentry; +	return inode_has_perm(cred, inode, av, &ad, 0); +} + +/* Same as inode_has_perm, but pass explicit audit data containing +   the path to help the auditing code to more easily generate the +   pathname if needed. */ +static inline int path_has_perm(const struct cred *cred, +				struct path *path, +				u32 av) +{ +	struct inode *inode = path->dentry->d_inode; +	struct common_audit_data ad; + +	COMMON_AUDIT_DATA_INIT(&ad, PATH); +	ad.u.path = *path;  	return inode_has_perm(cred, inode, av, &ad, 0);  } @@ -1529,8 +1544,8 @@ static int file_has_perm(const struct cred *cred,  	u32 sid = cred_sid(cred);  	int rc; -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.path = file->f_path; +	COMMON_AUDIT_DATA_INIT(&ad, PATH); +	ad.u.path = file->f_path;  	if (sid != fsec->sid) {  		rc = avc_has_perm(sid, fsec->sid, @@ -1568,8 +1583,8 @@ static int may_create(struct inode *dir,  	sid = tsec->sid;  	newsid = tsec->create_sid; -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.path.dentry = dentry; +	COMMON_AUDIT_DATA_INIT(&ad, DENTRY); +	ad.u.dentry = dentry;  	rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,  			  DIR__ADD_NAME | DIR__SEARCH, @@ -1621,8 +1636,8 @@ static int may_link(struct inode *dir,  	dsec = dir->i_security;  	isec = dentry->d_inode->i_security; -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.path.dentry = dentry; +	COMMON_AUDIT_DATA_INIT(&ad, DENTRY); +	ad.u.dentry = dentry;  	av = DIR__SEARCH;  	av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); @@ -1667,9 +1682,9 @@ static inline int may_rename(struct inode *old_dir,  	old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);  	new_dsec = new_dir->i_security; -	COMMON_AUDIT_DATA_INIT(&ad, FS); +	COMMON_AUDIT_DATA_INIT(&ad, DENTRY); -	ad.u.fs.path.dentry = old_dentry; +	ad.u.dentry = old_dentry;  	rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,  			  DIR__REMOVE_NAME | DIR__SEARCH, &ad);  	if (rc) @@ -1685,7 +1700,7 @@ static inline int may_rename(struct inode *old_dir,  			return rc;  	} -	ad.u.fs.path.dentry = new_dentry; +	ad.u.dentry = new_dentry;  	av = DIR__ADD_NAME | DIR__SEARCH;  	if (new_dentry->d_inode)  		av |= DIR__REMOVE_NAME; @@ -1895,7 +1910,7 @@ static int selinux_quota_on(struct dentry *dentry)  {  	const struct cred *cred = current_cred(); -	return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); +	return dentry_has_perm(cred, dentry, FILE__QUOTAON);  }  static int selinux_syslog(int type) @@ -1992,8 +2007,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)  			return rc;  	} -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.path = bprm->file->f_path; +	COMMON_AUDIT_DATA_INIT(&ad, PATH); +	ad.u.path = bprm->file->f_path;  	if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)  		new_tsec->sid = old_tsec->sid; @@ -2121,7 +2136,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,  	/* Revalidate access to inherited open files. */ -	COMMON_AUDIT_DATA_INIT(&ad, FS); +	COMMON_AUDIT_DATA_INIT(&ad, INODE);  	spin_lock(&files->file_lock);  	for (;;) { @@ -2469,8 +2484,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)  	if (flags & MS_KERNMOUNT)  		return 0; -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.path.dentry = sb->s_root; +	COMMON_AUDIT_DATA_INIT(&ad, DENTRY); +	ad.u.dentry = sb->s_root;  	return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);  } @@ -2479,8 +2494,8 @@ static int selinux_sb_statfs(struct dentry *dentry)  	const struct cred *cred = current_cred();  	struct common_audit_data ad; -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.path.dentry = dentry->d_sb->s_root; +	COMMON_AUDIT_DATA_INIT(&ad, DENTRY); +	ad.u.dentry = dentry->d_sb->s_root;  	return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);  } @@ -2496,8 +2511,7 @@ static int selinux_mount(char *dev_name,  		return superblock_has_perm(cred, path->mnt->mnt_sb,  					   FILESYSTEM__REMOUNT, NULL);  	else -		return dentry_has_perm(cred, path->mnt, path->dentry, -				       FILE__MOUNTON); +		return path_has_perm(cred, path, FILE__MOUNTON);  }  static int selinux_umount(struct vfsmount *mnt, int flags) @@ -2630,14 +2644,14 @@ static int selinux_inode_readlink(struct dentry *dentry)  {  	const struct cred *cred = current_cred(); -	return dentry_has_perm(cred, NULL, dentry, FILE__READ); +	return dentry_has_perm(cred, dentry, FILE__READ);  }  static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)  {  	const struct cred *cred = current_cred(); -	return dentry_has_perm(cred, NULL, dentry, FILE__READ); +	return dentry_has_perm(cred, dentry, FILE__READ);  }  static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) @@ -2654,8 +2668,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag  	if (!mask)  		return 0; -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.inode = inode; +	COMMON_AUDIT_DATA_INIT(&ad, INODE); +	ad.u.inode = inode;  	if (from_access)  		ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; @@ -2680,16 +2694,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)  	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |  			ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) -		return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); +		return dentry_has_perm(cred, dentry, FILE__SETATTR); -	return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); +	return dentry_has_perm(cred, dentry, FILE__WRITE);  }  static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)  {  	const struct cred *cred = current_cred(); +	struct path path; + +	path.dentry = dentry; +	path.mnt = mnt; -	return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR); +	return path_has_perm(cred, &path, FILE__GETATTR);  }  static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) @@ -2710,7 +2728,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)  	/* Not an attribute we recognize, so just check the  	   ordinary setattr permission. */ -	return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); +	return dentry_has_perm(cred, dentry, FILE__SETATTR);  }  static int selinux_inode_setxattr(struct dentry *dentry, const char *name, @@ -2733,8 +2751,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,  	if (!inode_owner_or_capable(inode))  		return -EPERM; -	COMMON_AUDIT_DATA_INIT(&ad, FS); -	ad.u.fs.path.dentry = dentry; +	COMMON_AUDIT_DATA_INIT(&ad, DENTRY); +	ad.u.dentry = dentry;  	rc = avc_has_perm(sid, isec->sid, isec->sclass,  			  FILE__RELABELFROM, &ad); @@ -2797,14 +2815,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name)  {  	const struct cred *cred = current_cred(); -	return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); +	return dentry_has_perm(cred, dentry, FILE__GETATTR);  }  static int selinux_inode_listxattr(struct dentry *dentry)  {  	const struct cred *cred = current_cred(); -	return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); +	return dentry_has_perm(cred, dentry, FILE__GETATTR);  }  static int selinux_inode_removexattr(struct dentry *dentry, const char *name)  |