From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from canpmsgout07.his.huawei.com (canpmsgout07.his.huawei.com [113.46.200.222]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B1B5374E66; Mon, 11 May 2026 11:30:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.222 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778499056; cv=none; b=BmS3sD45xvYYZRGyuMMc+ybznwnGRU/E4UuFaTJnfcHSLU5G2q7ZgUpIDnFgd8JrtQpYHky9mHa/QfiOQ7ifNbfzZnDhGaxZ/C3S2xLFuic9TWN6GIvkpKXe7SqQodtOwac5YviUuF4p4smuOS6CsuME5xXEk1KnNJH4a5xG1Ro= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778499056; c=relaxed/simple; bh=+yjkn4HBuA/UyhKfR+d394Bjxs+3MnkK17zGluVy8hs=; h=Message-ID:Date:MIME-Version:Subject:To:CC:References:From: In-Reply-To:Content-Type; b=kYCGnVkNY0zBq/1PD5D94qcPDcjFBXgHCb79pi4cA1oKA4b9GQKIQZ3m29MViGFn/YoWsyRw725GWBNSwU4JFhILArRSuj26k+cYt/KfDR9gRt1dghF9jI/3WHsNqwwzZ8zTmRjkKQzwXcEvCDnTloQBVX7K+GI/ZuGkWryzx8A= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=A7gfGf9I; arc=none smtp.client-ip=113.46.200.222 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="A7gfGf9I" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=hZY77WY1R4lZKqkiJYVx90NM7cypXm7b/K/Dl6ostWU=; b=A7gfGf9I2mWtoGk1twpeKdsTWxHRCoqkxK6h8sqAufJacFPxPk7J5UV8oj4BBjTyooxVD2Cki IZBX0lyWqVPhijn1Ra4jjJgWV2oQvMFsHXLFq2R6ycKWvoUQXNa+lNIZBbmfXSzS+9wfOLM4NXI bc1oxF4bSdMbsjNUg+iYH3U= Received: from mail.maildlp.com (unknown [172.19.163.163]) by canpmsgout07.his.huawei.com (SkyGuard) with ESMTPS id 4gDcm153LszLlSL; Mon, 11 May 2026 19:23:13 +0800 (CST) Received: from dggpemf500011.china.huawei.com (unknown [7.185.36.131]) by mail.maildlp.com (Postfix) with ESMTPS id 2B9494048B; Mon, 11 May 2026 19:30:49 +0800 (CST) Received: from [10.67.109.254] (10.67.109.254) by dggpemf500011.china.huawei.com (7.185.36.131) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Mon, 11 May 2026 19:30:44 +0800 Message-ID: <79c14bee-b1f5-4d70-8345-6582d6cf0128@huawei.com> Date: Mon, 11 May 2026 19:30:44 +0800 Precedence: bulk X-Mailing-List: linux-doc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v13 04/15] arm64: kexec_file: Fix potential buffer overflow in prepare_elf_headers() To: Breno Leitao CC: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , References: <20260511030454.1730881-1-ruanjinjie@huawei.com> <20260511030454.1730881-5-ruanjinjie@huawei.com> From: Jinjie Ruan In-Reply-To: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To dggpemf500011.china.huawei.com (7.185.36.131) On 5/11/2026 5:46 PM, Breno Leitao wrote: > On Mon, May 11, 2026 at 11:04:43AM +0800, Jinjie Ruan wrote: >> There is a race condition between the kexec_load() system call >> (crash kernel loading path) and memory hotplug operations that can >> lead to buffer overflow and potential kernel crash. >> >> During prepare_elf_headers(), the following steps occur: >> 1. The first for_each_mem_range() queries current System RAM memory ranges >> 2. Allocates buffer based on queried count >> 3. The 2st for_each_mem_range() populates ranges from memblock >> >> If memory hotplug occurs between step 1 and step 3, the number of ranges >> can increase, causing out-of-bounds write when populating cmem->ranges[]. >> >> This happens because kexec_load() uses kexec_trylock (atomic_t) while >> memory hotplug uses device_hotplug_lock (mutex), so they don't serialize >> with each other. >> >> Add the explicit bounds checking to prevent out-of-bounds access. > > It seems you have a TOCTOU type of issue, and this seems to be shrinking > the window, but not fully solving it? Hi Breno, Thanks for your comments regarding the TOCTOU issue. You are correct that the current bounds checking only "shrinks the window" and prevents a kernel crash, but doesn't fully guarantee header consistency if a race occurs. In my local environment, this race is extremely difficult to reproduce, but it is theoretically possible. To address this properly for arm64, I am considering two steps: - For this patch: I will change the return value to -EAGAIN and keep the bounds check. This ensures that even if a race happens, the kernel remains safe (no OOB access), and user-space is notified to retry. - Long-term solution: A better way to solve this is to implement ARM64 CRASH_HOTPLUG support (similar to x86). With crash hotplug, the kernel will automatically re-generate the crash headers whenever a memory hotplug event occurs. This makes the TOCTOU during the initial kexec_load less critical, as any transient inconsistency will be immediately corrected by the subsequent hotplug handler. Does it make sense to you to use this patch as a safety guard first, and then I (or someone else) follow up with the full CRASH_HOTPLUG support for arm64 as [1]? [1]: https://lore.kernel.org/all/20260402081459.635022-1-ruanjinjie@huawei.com/ Best regards, Jinjie > >> Cc: Catalin Marinas >> Cc: Will Deacon >> Cc: Andrew Morton >> Cc: Baoquan He >> Cc: Breno Leitao >> Cc: stable@vger.kernel.org >> Fixes: 3751e728cef2 ("arm64: kexec_file: add crash dump support") >> Closes: https://sashiko.dev/#/patchset/20260323072745.2481719-1-ruanjinjie%40huawei.com >> Signed-off-by: Jinjie Ruan >> --- >> arch/arm64/kernel/machine_kexec_file.c | 5 +++++ >> 1 file changed, 5 insertions(+) >> >> diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c >> index e31fabed378a..a67e7b1abbab 100644 >> --- a/arch/arm64/kernel/machine_kexec_file.c >> +++ b/arch/arm64/kernel/machine_kexec_file.c >> @@ -59,6 +59,11 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) >> cmem->max_nr_ranges = nr_ranges; >> cmem->nr_ranges = 0; >> for_each_mem_range(i, &start, &end) { >> + if (cmem->nr_ranges >= cmem->max_nr_ranges) { >> + ret = -ENOMEM; > > -ENOMEM seems to be the the wrong errno. This isn't an allocation > failure; it's a transient race. -EBUSY or -EAGAIN would be more honest