]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drivers/base/memory: fix memory block reference leak in poison accounting
authorMuchun Song <songmuchun@bytedance.com>
Tue, 28 Apr 2026 08:52:18 +0000 (16:52 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Thu, 14 May 2026 00:40:03 +0000 (17:40 -0700)
memblk_nr_poison_inc() and memblk_nr_poison_sub() look up a memory block
via find_memory_block_by_id(), which acquires a reference to the memory
block device.

Both helpers use the returned memory block without dropping that
reference, leaking the device reference on each successful lookup.  Drop
the reference after updating nr_hwpoison.

Link: https://lore.kernel.org/20260428085219.1316047-3-songmuchun@bytedance.com
Fixes: 5033091de814 ("mm/hwpoison: introduce per-memory_block hwpoison counter")
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
Acked-by: Oscar Salvador <osalvador@suse.de>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Huang, Ying" <huang.ying.caritas@gmail.com>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
drivers/base/memory.c

index f806a683b7672221ce49b613131cac6d8d2dab27..6981b55d582ace801e413616b537bf20bcf8c45a 100644 (file)
@@ -1230,8 +1230,10 @@ void memblk_nr_poison_inc(unsigned long pfn)
        const unsigned long block_id = pfn_to_block_id(pfn);
        struct memory_block *mem = find_memory_block_by_id(block_id);
 
-       if (mem)
+       if (mem) {
                atomic_long_inc(&mem->nr_hwpoison);
+               put_device(&mem->dev);
+       }
 }
 
 void memblk_nr_poison_sub(unsigned long pfn, long i)
@@ -1239,8 +1241,10 @@ void memblk_nr_poison_sub(unsigned long pfn, long i)
        const unsigned long block_id = pfn_to_block_id(pfn);
        struct memory_block *mem = find_memory_block_by_id(block_id);
 
-       if (mem)
+       if (mem) {
                atomic_long_sub(i, &mem->nr_hwpoison);
+               put_device(&mem->dev);
+       }
 }
 
 static unsigned long memblk_nr_poison(struct memory_block *mem)