summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Pau Monne <roger.pau@citrix.com>2021-06-07 15:13:15 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-06-10 13:39:29 +0200
commit6b53db8c4c14b4e7256f058d202908b54a7b85b4 (patch)
treedc957af7370481d9cfca2b2db9fa08ae2f6b39a3
parent316de9a88c83c672c18d35bd76034d84e3769fe9 (diff)
xen-netback: take a reference to the RX task thread
commit 107866a8eb0b664675a260f1ba0655010fac1e08 upstream. Do this in order to prevent the task from being freed if the thread returns (which can be triggered by the frontend) before the call to kthread_stop done as part of the backend tear down. Not taking the reference will lead to a use-after-free in that scenario. Such reference was taken before but dropped as part of the rework done in 2ac061ce97f4. Reintroduce the reference taking and add a comment this time explaining why it's needed. This is XSA-374 / CVE-2021-28691. Fixes: 2ac061ce97f4 ('xen/netback: cleanup init and deinit code') Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Cc: stable@vger.kernel.org Reviewed-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Juergen Gross <jgross@suse.com> Signed-off-by: Juergen Gross <jgross@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/xen-netback/interface.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index e02a4fbb74de..7ce9807fc24c 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -685,6 +685,7 @@ static void xenvif_disconnect_queue(struct xenvif_queue *queue)
{
if (queue->task) {
kthread_stop(queue->task);
+ put_task_struct(queue->task);
queue->task = NULL;
}
@@ -745,6 +746,11 @@ int xenvif_connect_data(struct xenvif_queue *queue,
if (IS_ERR(task))
goto kthread_err;
queue->task = task;
+ /*
+ * Take a reference to the task in order to prevent it from being freed
+ * if the thread function returns before kthread_stop is called.
+ */
+ get_task_struct(task);
task = kthread_run(xenvif_dealloc_kthread, queue,
"%s-dealloc", queue->name);