[vz8,2/2] ve,kthread: fix use-after-return.

Submitted by Andrey Ryabinin on Oct. 17, 2019, 12:49 p.m.

Details

Message ID 20191017124905.22122-2-aryabinin@virtuozzo.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Andrey Ryabinin Oct. 17, 2019, 12:49 p.m.
__kthread_create_ve() passes pointer to the data on stack to
another thread, and return immidiately causing use-after-return.

Fix this by moving all in upper function which waits
another thread finishes it's job.

https://jira.sw.ru/browse/PSBM-93708
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 kernel/kthread.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

Patch hide | download patch | download mbox

diff --git a/kernel/kthread.c b/kernel/kthread.c
index 4ba351b3cf66..68c49a397c6a 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -303,19 +303,6 @@  static void kthread_create_fn(struct kthread_work *w)
 	create_kthread_flags(work->info, work->flags);
 }
 
-static void __kthread_create_ve(struct kthread_create_info *create,
-			        struct ve_struct *ve,
-				unsigned long flags)
-{
-	struct kthread_create_work work = {
-		KTHREAD_WORK_INIT(work.work, kthread_create_fn),
-		.info = create,
-		.flags = flags,
-	};
-
-	kthread_queue_work(ve->kthreadd_worker, &work.work);
-	return;
-}
 #endif
 static void kthread_create_add(struct kthread_create_info *create)
 {
@@ -335,6 +322,9 @@  struct task_struct *__kthread_create_on_node_ve(struct ve_struct *ve,
 						va_list args)
 {
 	DECLARE_COMPLETION_ONSTACK(done);
+	struct kthread_create_work work = {
+		KTHREAD_WORK_INIT(work.work, kthread_create_fn),
+	};
 	struct task_struct *task;
 	struct kthread_create_info *create = kmalloc(sizeof(*create),
 						     GFP_KERNEL);
@@ -348,8 +338,11 @@  struct task_struct *__kthread_create_on_node_ve(struct ve_struct *ve,
 
 #ifdef CONFIG_VE
 	if (!ve_is_super(ve))
-		__kthread_create_ve(create, ve, flags);
-	else
+	{
+		work.info = create;
+		work.flags = flags;
+		kthread_queue_work(ve->kthreadd_worker, &work.work);
+	} else
 #endif
 		kthread_create_add(create);
 	/*