diff options
| -rw-r--r-- | include/linux/task_work.h | 4 | ||||
| -rw-r--r-- | kernel/irq/manage.c | 2 | ||||
| -rw-r--r-- | security/keys/internal.h | 4 | ||||
| -rw-r--r-- | security/keys/keyctl.c | 14 | ||||
| -rw-r--r-- | security/keys/process_keys.c | 5 | 
5 files changed, 17 insertions, 12 deletions
diff --git a/include/linux/task_work.h b/include/linux/task_work.h index 294d5d5e90b..627421c0e10 100644 --- a/include/linux/task_work.h +++ b/include/linux/task_work.h @@ -10,14 +10,12 @@ typedef void (*task_work_func_t)(struct task_work *);  struct task_work {  	struct hlist_node hlist;  	task_work_func_t func; -	void *data;  };  static inline void -init_task_work(struct task_work *twork, task_work_func_t func, void *data) +init_task_work(struct task_work *twork, task_work_func_t func)  {  	twork->func = func; -	twork->data = data;  }  int task_work_add(struct task_struct *task, struct task_work *twork, bool); diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 8c548232ba3..d1dd54734ce 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -830,7 +830,7 @@ static int irq_thread(void *data)  	sched_setscheduler(current, SCHED_FIFO, ¶m); -	init_task_work(&on_exit_work, irq_thread_dtor, NULL); +	init_task_work(&on_exit_work, irq_thread_dtor);  	task_work_add(current, &on_exit_work, false);  	while (!irq_wait_for_interrupt(action)) { diff --git a/security/keys/internal.h b/security/keys/internal.h index 3dcbf86b0d3..b510a316874 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -148,6 +148,10 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,  #define KEY_LOOKUP_PARTIAL	0x02  #define KEY_LOOKUP_FOR_UNLINK	0x04 +struct kludge {	/* this will die off very soon */ +	struct task_work twork; +	struct cred *cred; +};  extern long join_session_keyring(const char *name);  extern void key_change_session_keyring(struct task_work *twork); diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 0f5b3f02729..26723caaad0 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1456,7 +1456,8 @@ long keyctl_session_to_parent(void)  {  	struct task_struct *me, *parent;  	const struct cred *mycred, *pcred; -	struct task_work *newwork, *oldwork; +	struct kludge *newwork; +	struct task_work *oldwork;  	key_ref_t keyring_r;  	struct cred *cred;  	int ret; @@ -1466,7 +1467,7 @@ long keyctl_session_to_parent(void)  		return PTR_ERR(keyring_r);  	ret = -ENOMEM; -	newwork = kmalloc(sizeof(struct task_work), GFP_KERNEL); +	newwork = kmalloc(sizeof(struct kludge), GFP_KERNEL);  	if (!newwork)  		goto error_keyring; @@ -1478,7 +1479,8 @@ long keyctl_session_to_parent(void)  		goto error_newwork;  	cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); -	init_task_work(newwork, key_change_session_keyring, cred); +	init_task_work(&newwork->twork, key_change_session_keyring); +	newwork->cred = cred;  	me = current;  	rcu_read_lock(); @@ -1527,18 +1529,18 @@ long keyctl_session_to_parent(void)  	/* the replacement session keyring is applied just prior to userspace  	 * restarting */ -	ret = task_work_add(parent, newwork, true); +	ret = task_work_add(parent, &newwork->twork, true);  	if (!ret)  		newwork = NULL;  unlock:  	write_unlock_irq(&tasklist_lock);  	rcu_read_unlock();  	if (oldwork) { -		put_cred(oldwork->data); +		put_cred(container_of(oldwork, struct kludge, twork)->cred);  		kfree(oldwork);  	}  	if (newwork) { -		put_cred(newwork->data); +		put_cred(newwork->cred);  		kfree(newwork);  	}  	return ret; diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 4ad54eea1ea..c9b07c97d7f 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -837,9 +837,10 @@ error:  void key_change_session_keyring(struct task_work *twork)  {  	const struct cred *old = current_cred(); -	struct cred *new = twork->data; +	struct kludge *p = container_of(twork, struct kludge, twork); +	struct cred *new = p->cred; -	kfree(twork); +	kfree(p);  	if (unlikely(current->flags & PF_EXITING)) {  		put_cred(new);  		return;  |