lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Fri, 3 May 2024 19:23:48 +0300
From: Fedor Pchelkin <pchelkin@...ras.ru>
To: Robin Murphy <robin.murphy@....com>
Cc: Xiang Chen <chenxiang66@...ilicon.com>, Christoph Hellwig <hch@....de>, 
	Marek Szyprowski <m.szyprowski@...sung.com>, Barry Song <21cnbao@...il.com>, iommu@...ts.linux.dev, 
	linux-kernel@...r.kernel.org, Alexey Khoroshilov <khoroshilov@...ras.ru>, 
	lvc-project@...uxtesting.org
Subject: Re: [PATCH 1/2] dma-mapping: benchmark: fix up kthread creation
 error handling

Robin Murphy wrote:
> On 2024-05-02 5:18 pm, Fedor Pchelkin wrote:
> > If a kthread creation fails for some reason then uninitialized members of
> > the tasks array will be accessed on the error path since it is allocated
> > by kmalloc_array().
> > 
> > Limit the bound in such case.
> 
> I don't think this is right... The put_task_struct() calls on the error 
> path are supposed to balance the get_task_struct() calls which only 
> happen *after* all the threads are successfully created - see commit 

Thanks, Robin! You're right. Now I see this..

> d17405d52bac ("dma-mapping: benchmark: fix kernel crash when 
> dma_map_single fails") - although I now wonder whether that might have 
> been better done by replacing kthread_stop() with kthread_stop_put(). It 
> doesn't look like we've ever actually tried to free any previous threads 
> from the point of allocation failure.

It should have looked like the diff below, as you say. And it's probably
better to merge the two patches together so that we eliminate task leaks
in case kthread_stop_put() returns error like it is below.

Will rework that in v2.

diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c
index 02205ab53b7e..3b7658ce1599 100644
--- a/kernel/dma/map_benchmark.c
+++ b/kernel/dma/map_benchmark.c
@@ -118,6 +118,8 @@ static int do_map_benchmark(struct map_benchmark_data *map)
                if (IS_ERR(tsk[i])) {
                        pr_err("create dma_map thread failed\n");
                        ret = PTR_ERR(tsk[i]);
+                       while (--i >= 0)
+                               kthread_stop(tsk[i]);
                        goto out;
                }
 
@@ -141,7 +143,7 @@ static int do_map_benchmark(struct map_benchmark_data *map)
 
        /* wait for the completion of benchmark threads */
        for (i = 0; i < threads; i++) {
-               ret = kthread_stop(tsk[i]);
+               ret = kthread_stop_put(tsk[i]);
                if (ret)
                        goto out;
        }
@@ -170,8 +172,6 @@ static int do_map_benchmark(struct map_benchmark_data *map)
        }
 
 out:
-       for (i = 0; i < threads; i++)
-               put_task_struct(tsk[i]);
        put_device(map->dev);
        kfree(tsk);
        return ret;

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ