diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/keys/internal.h | 2 | ||||
| -rw-r--r-- | security/keys/keyctl.c | 26 | ||||
| -rw-r--r-- | security/keys/process_keys.c | 5 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 5 | ||||
| -rw-r--r-- | security/selinux/include/classmap.h | 4 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 2 | ||||
| -rw-r--r-- | security/selinux/selinuxfs.c | 6 | 
7 files changed, 22 insertions, 28 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h index 3dcbf86b0d3..c246ba5d43a 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -149,7 +149,7 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,  #define KEY_LOOKUP_FOR_UNLINK	0x04  extern long join_session_keyring(const char *name); -extern void key_change_session_keyring(struct task_work *twork); +extern void key_change_session_keyring(struct callback_head *twork);  extern struct work_struct key_gc_work;  extern unsigned key_gc_delay; diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 0f5b3f02729..f1b59ae39d7 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1456,7 +1456,7 @@ long keyctl_session_to_parent(void)  {  	struct task_struct *me, *parent;  	const struct cred *mycred, *pcred; -	struct task_work *newwork, *oldwork; +	struct callback_head *newwork, *oldwork;  	key_ref_t keyring_r;  	struct cred *cred;  	int ret; @@ -1466,19 +1466,17 @@ long keyctl_session_to_parent(void)  		return PTR_ERR(keyring_r);  	ret = -ENOMEM; -	newwork = kmalloc(sizeof(struct task_work), GFP_KERNEL); -	if (!newwork) -		goto error_keyring;  	/* our parent is going to need a new cred struct, a new tgcred struct  	 * and new security data, so we allocate them here to prevent ENOMEM in  	 * our parent */  	cred = cred_alloc_blank();  	if (!cred) -		goto error_newwork; +		goto error_keyring; +	newwork = &cred->rcu;  	cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); -	init_task_work(newwork, key_change_session_keyring, cred); +	init_task_work(newwork, key_change_session_keyring);  	me = current;  	rcu_read_lock(); @@ -1488,6 +1486,7 @@ long keyctl_session_to_parent(void)  	oldwork = NULL;  	parent = me->real_parent; +	task_lock(parent);  	/* the parent mustn't be init and mustn't be a kernel thread */  	if (parent->pid <= 1 || !parent->mm)  		goto unlock; @@ -1531,20 +1530,15 @@ long keyctl_session_to_parent(void)  	if (!ret)  		newwork = NULL;  unlock: +	task_unlock(parent);  	write_unlock_irq(&tasklist_lock);  	rcu_read_unlock(); -	if (oldwork) { -		put_cred(oldwork->data); -		kfree(oldwork); -	} -	if (newwork) { -		put_cred(newwork->data); -		kfree(newwork); -	} +	if (oldwork) +		put_cred(container_of(oldwork, struct cred, rcu)); +	if (newwork) +		put_cred(cred);  	return ret; -error_newwork: -	kfree(newwork);  error_keyring:  	key_ref_put(keyring_r);  	return ret; diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 4ad54eea1ea..54339cfd673 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -834,12 +834,11 @@ error:   * Replace a process's session keyring on behalf of one of its children when   * the target  process is about to resume userspace execution.   */ -void key_change_session_keyring(struct task_work *twork) +void key_change_session_keyring(struct callback_head *twork)  {  	const struct cred *old = current_cred(); -	struct cred *new = twork->data; +	struct cred *new = container_of(twork, struct cred, rcu); -	kfree(twork);  	if (unlikely(current->flags & PF_EXITING)) {  		put_cred(new);  		return; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 372ec6502aa..9292a8971e6 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2157,8 +2157,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,  						get_file(devnull);  					} else {  						devnull = dentry_open( -							dget(selinux_null), -							mntget(selinuxfs_mount), +							&selinux_null,  							O_RDWR, cred);  						if (IS_ERR(devnull)) {  							devnull = NULL; @@ -2717,7 +2716,7 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)  			ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))  		return dentry_has_perm(cred, dentry, FILE__SETATTR); -	if (ia_valid & ATTR_SIZE) +	if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE))  		av |= FILE__OPEN;  	return dentry_has_perm(cred, dentry, av); diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index b8c53723e09..df2de54a958 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -145,7 +145,9 @@ struct security_class_mapping secclass_map[] = {  	    "node_bind", "name_connect", NULL } },  	{ "memprotect", { "mmap_zero", NULL } },  	{ "peer", { "recv", NULL } }, -	{ "capability2", { "mac_override", "mac_admin", "syslog", NULL } }, +	{ "capability2", +	  { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", +	    NULL } },  	{ "kernel_service", { "use_as_override", "create_files_as", NULL } },  	{ "tun_socket",  	  { COMMON_SOCK_PERMS, NULL } }, diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index dde2005407a..6d3885165d1 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -221,7 +221,7 @@ extern void selinux_status_update_policyload(int seqno);  extern void selinux_complete_init(void);  extern int selinux_disable(void);  extern void exit_sel_fs(void); -extern struct dentry *selinux_null; +extern struct path selinux_null;  extern struct vfsmount *selinuxfs_mount;  extern void selnl_notify_setenforce(int val);  extern void selnl_notify_policyload(u32 seqno); diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 3ad29025128..298e695d682 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -1297,7 +1297,7 @@ out:  #define NULL_FILE_NAME "null" -struct dentry *selinux_null; +struct path selinux_null;  static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,  					    size_t count, loff_t *ppos) @@ -1838,7 +1838,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)  	init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3));  	d_add(dentry, inode); -	selinux_null = dentry; +	selinux_null.dentry = dentry;  	dentry = sel_make_dir(sb->s_root, "avc", &sel_last_ino);  	if (IS_ERR(dentry)) { @@ -1912,7 +1912,7 @@ static int __init init_sel_fs(void)  		return err;  	} -	selinuxfs_mount = kern_mount(&sel_fs_type); +	selinux_null.mnt = selinuxfs_mount = kern_mount(&sel_fs_type);  	if (IS_ERR(selinuxfs_mount)) {  		printk(KERN_ERR "selinuxfs:  could not mount!\n");  		err = PTR_ERR(selinuxfs_mount);  |