mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Coiby Xu" <coiby.xu@gmail.com>
Cc: "Andrew Morton" <akpm@linux-foundation.org>,
	"Will Deacon" <will@kernel.org>,
	kexec@lists.infradead.org, "Pratyush Yadav" <pratyush@kernel.org>,
	"Dave Young" <ruirui.yang@linux.dev>,
	"Mike Rapoport" <rppt@kernel.org>,
	linux-arm-kernel@lists.infradead.org,
	"Pasha Tatashin" <pasha.tatashin@soleen.com>,
	"Baoquan He" <baoquan.he@linux.dev>,
	"Sourabh Jain" <sourabhjain@linux.ibm.com>,
	"open list" <linux-kernel@vger.kernel.org>,
	"Jinjie Ruan" <ruanjinjie@huawei.com>
Subject: Re: [PATCH v5 7/9] crash_dump: Check the function return codes in restore_dm_crypt_keys_to_thread_keyring
Date: Wed, 09 Sep 2026 00:49:19 +0000	[thread overview]
Message-ID: <20260909004919.7802D1F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260909003657.1570544-8-coiby.xu@gmail.com>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:

New issues:
- [Medium] Memory and reference leak of the key returned by key_create_or_update() on the success path.
- [Medium] Incorrect return value assignment from `dm_crypt_keys_read()` breaks the caller's success check for empty key sets.

Pre-existing issues:
- [High] Missing validation of `dm_crypt_keys_addr` leads to arbitrary memory reads.
- [High] Buffer over-read from single mapped page in get_keys_from_kdump_reserved_memory().
- [High] Missing validation on parsed key attributes leads to massive Heap Out-of-Bounds reads and Information Leak.
- [Medium] Double fetch of the key count from untrusted memory leads to Heap Out-of-Bounds read.
--

commit e9dcb18898d315e8ec7102932e9391f9c0892b97
Author: Coiby Xu <coiby.xu@gmail.com>
Subject: crash_dump: Check the function return codes in restore_dm_crypt_keys_to_thread_keyring

This commit adds return code checking for dm_crypt_keys_read() and
add_key_to_keyring() to properly abort when reading old memory or
allocating a keyring fails. It also deletes unused code related to
the key reference.

> diff --git a/kernel/crash_dump_dm_crypt.c b/kernel/crash_dump_dm_crypt.c
> index b8fe630462cfa..bc70fbb79e0f6 100644
> --- a/kernel/crash_dump_dm_crypt.c
> +++ b/kernel/crash_dump_dm_crypt.c
> @@ -66,7 +66,7 @@ static int add_key_to_keyring(struct dm_crypt_key *dm_key,
>  			      key_ref_t keyring_ref)
>  {
>  	key_ref_t key_ref;
> -	int r;
> +	int r = 0;
>  
>  	/* create or update the requested key and add it to the target keyring */
>  	key_ref = key_create_or_update(keyring_ref, "user", dm_key->key_desc,
> @@ -74,8 +74,6 @@ static int add_key_to_keyring(struct dm_crypt_key *dm_key,
>  				       KEY_USR_ALL, KEY_ALLOC_IN_QUOTA);
>  
>  	if (!IS_ERR(key_ref)) {
> -		r = key_ref_to_ptr(key_ref)->serial;
> -		key_ref_put(key_ref);
>  		pr_debug("Success adding key %s\n", dm_key->key_desc);

[Severity: Medium]
Does removing key_ref_put() here leak the key reference?

key_create_or_update() returns a key reference specifically for the caller
with an incremented usage count, so without key_ref_put(), the key's usage
count might be permanently elevated, preventing it from ever being garbage
collected.

>  	} else {
>  		r = PTR_ERR(key_ref);

[ ... ]

> @@ -134,9 +132,14 @@ static int restore_dm_crypt_keys_to_thread_keyring(void)
>  	}
>  
>  	addr = dm_crypt_keys_addr;
> -	dm_crypt_keys_read((char *)&key_count, sizeof(key_count), &addr);
> +	ret = dm_crypt_keys_read((char *)&key_count, sizeof(key_count), &addr);

[Severity: High]
This is a pre-existing issue, but is it safe to read from dm_crypt_keys_addr
without verifying if it was ever initialized by the command-line argument?

If the kdump kernel is booted without the dmcryptkeys= parameter,
dm_crypt_keys_addr might remain 0, leading to arbitrary memory reads
when this sysfs attribute is triggered.

> +	if (ret < 0) {
> +		pr_err("Failed to read the number of dm-crypt keys\n");
> +		goto out;
> +	}
> +

[ ... ]

> @@ -151,12 +154,18 @@ static int restore_dm_crypt_keys_to_thread_keyring(void)
>  		goto out;
>  	}
>  
> -	dm_crypt_keys_read((char *)keys_header, keys_header_size, &addr);
> +	ret = dm_crypt_keys_read((char *)keys_header, keys_header_size, &addr);

[Severity: Medium]
If dm_crypt_keys_read() succeeds, it returns a positive byte count which is
assigned to ret. If there are no keys and the loop below doesn't execute,
will this function incorrectly return a positive value instead of 0?

The caller config_keys_restore_store() expects !ret to set restore = true,
which would fail if ret is a positive byte count.

> +	if (ret < 0) {
> +		pr_err("Failed to read dm-crypt keys\n");
> +		goto out;
> +	}
>  
>  	for (int i = 0; i < keys_header->total_keys; i++) {

[Severity: Medium]
This is a pre-existing issue, but does the second read from oldmem physically
overwrite keys_header->total_keys with unvalidated data?

If oldmem changes concurrently or the read partially fails, the newly fetched
total_keys can exceed the originally validated key_count. The loop bounds
check uses this unvalidated bound, potentially causing a heap out-of-bounds
read.

>  		key = &keys_header->keys[i];
>  		pr_debug("Get key (size=%u)\n", key->key_size);
> -		add_key_to_keyring(key, keyring_ref);
> +		ret = add_key_to_keyring(key, keyring_ref);

[Severity: High]
This isn't a bug introduced by this patch, but are key->key_size and
key->key_desc validated before being passed to add_key_to_keyring()?

The completely untrusted key_size is passed as the payload length to
key_create_or_update(), which might read far out-of-bounds from dm_key->data
and embed leaked kernel heap memory into the key payload. Additionally,
key_desc is not checked for null-termination.

> +		if (ret)
> +			break;
>  	}

[ ... ]

While reviewing this file, I also noticed another pre-existing issue in
get_keys_from_kdump_reserved_memory():

kernel/crash_dump_dm_crypt.c:get_keys_from_kdump_reserved_memory() {
    ...
	keys_header_loaded = kmap_local_page(pfn_to_page(
		kexec_crash_image->dm_crypt_keys_addr >> PAGE_SHIFT));
    ...
	memcpy(keys_header, keys_header_loaded, keys_header_size);
    ...
}

[Severity: High]
This isn't a bug introduced by this patch, but does this memcpy() read
past the boundaries of the mapped page?

kmap_local_page() establishes a mapping for exactly one page (4096 bytes),
but keys_header_size could be up to ~49KB. This will read far beyond the
single page boundary, potentially causing a kernel panic on architectures
where kmap_local_page() does not fall back to the direct map.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260909003657.1570544-1-coiby.xu@gmail.com?part=7

  reply	other threads:[~2026-09-09  0:49 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260909003657.1570544-1-coiby.xu@gmail.com>
2026-09-09  0:36 ` [PATCH v5 1/9] crash_dump: Fix potential double free and UAF of keys_header Coiby Xu
2026-09-09  0:53   ` sashiko-bot
2026-09-09 13:27     ` Coiby Xu
2026-09-09  0:36 ` [PATCH v5 2/9] crash_dump: Read the number of dm-crypt keys from reserved memory Coiby Xu
2026-09-09  0:52   ` sashiko-bot
2026-09-09  0:36 ` [PATCH v5 3/9] crash_dump: Disallow writing to dm-crypt configfs during kexec_file_load syscall Coiby Xu
2026-09-09  0:47   ` sashiko-bot
2026-09-09 13:29     ` Coiby Xu
2026-09-09  0:36 ` [PATCH v5 4/9] crash_dump: Free temporary dm-crypt keys_header buffer in kdump kernel Coiby Xu
2026-09-09  0:46   ` sashiko-bot
2026-09-09  0:36 ` [PATCH v5 5/9] crash_dump: Only use kexec_dprintk during the kexec_file_load syscall Coiby Xu
2026-09-09  0:47   ` sashiko-bot
2026-09-09  0:36 ` [PATCH v5 6/9] crash_dump: Improve readability of config_keys_restore_store Coiby Xu
2026-09-09  0:45   ` sashiko-bot
2026-09-09  0:36 ` [PATCH v5 7/9] crash_dump: Check the function return codes in restore_dm_crypt_keys_to_thread_keyring Coiby Xu
2026-09-09  0:49   ` sashiko-bot [this message]
2026-09-09  0:36 ` [PATCH v5 8/9] crash_dump: Disallow configfs/crash_dm_crypt_key/reuse if crash hotplug supported Coiby Xu
2026-09-09  0:53   ` sashiko-bot
2026-09-09  5:46   ` Randy Dunlap
2026-09-09 13:33     ` Coiby Xu
2026-09-09  0:36 ` [PATCH v5 9/9] Documentation: kdump: Add arm64 and ppc64le to encrypted dump target support list Coiby Xu
2026-09-09  0:38   ` sashiko-bot
2026-09-09  5:48   ` Randy Dunlap
2026-09-09 13:34     ` Coiby Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260909004919.7802D1F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=baoquan.he@linux.dev \
    --cc=coiby.xu@gmail.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pasha.tatashin@soleen.com \
    --cc=pratyush@kernel.org \
    --cc=rppt@kernel.org \
    --cc=ruanjinjie@huawei.com \
    --cc=ruirui.yang@linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=sourabhjain@linux.ibm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®