Commit 07ad45e0 authored by Miaoqian Lin's avatar Miaoqian Lin Committed by Heiko Carstens
Browse files

s390/mm: Fix memory leak in add_marker() when kvrealloc() fails



The function has a memory leak when kvrealloc() fails.
The function directly assigns NULL to the markers pointer, losing the
reference to the previously allocated memory. This causes kvfree() in
pt_dump_init() to free NULL instead of the leaked memory.

Fix by:
1. Using kvrealloc() uniformly for all allocations
2. Using a temporary variable to preserve the original pointer until
   allocation succeeds
3. Removing the error path that sets markers_cnt=0 to keep
   consistency between markers and markers_cnt

Found via static analysis and this is similar to commit 42378a9c
("bpf, verifier: Fix memory leak in array reallocation for stack state")

Fixes: d0e7915d ("s390/mm/ptdump: Generate address marker array dynamically")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarMiaoqian Lin <linmq006@gmail.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent b45873c3
Loading
Loading
Loading
Loading
+8 −13
Original line number Diff line number Diff line
@@ -291,16 +291,14 @@ static int ptdump_cmp(const void *a, const void *b)

static int add_marker(unsigned long start, unsigned long end, const char *name)
{
	size_t oldsize, newsize;

	oldsize = markers_cnt * sizeof(*markers);
	newsize = oldsize + 2 * sizeof(*markers);
	if (!oldsize)
		markers = kvmalloc(newsize, GFP_KERNEL);
	else
		markers = kvrealloc(markers, newsize, GFP_KERNEL);
	if (!markers)
		goto error;
	struct addr_marker *new;
	size_t newsize;

	newsize = (markers_cnt + 2) * sizeof(*markers);
	new = kvrealloc(markers, newsize, GFP_KERNEL);
	if (!new)
		return -ENOMEM;
	markers = new;
	markers[markers_cnt].is_start = 1;
	markers[markers_cnt].start_address = start;
	markers[markers_cnt].size = end - start;
@@ -312,9 +310,6 @@ static int add_marker(unsigned long start, unsigned long end, const char *name)
	markers[markers_cnt].name = name;
	markers_cnt++;
	return 0;
error:
	markers_cnt = 0;
	return -ENOMEM;
}

static int pt_dump_init(void)