* [PATCH v2 0/2] kexec: fix potential cmem->ranges out of bounds
@ 2023-12-20 5:57 fuqiang wang
2023-12-20 5:57 ` [PATCH v2 1/2] x86/kexec: Fix potential out of bounds in crash_setup_memmap_entries() fuqiang wang
2023-12-20 5:57 ` [PATCH v2 2/2] kexec: Fix potential out of bounds in crash_exclude_mem_range() fuqiang wang
0 siblings, 2 replies; 7+ messages in thread
From: fuqiang wang @ 2023-12-20 5:57 UTC (permalink / raw)
To: Baoquan He, Vivek Goyal, Dave Young, Yuntao Wang; +Cc: kexec, linux-kernel
This series tries to fix the potential cmem->ranges out of bounds.
On the v1 version, there are still some issues that need to be
discussed, as follows:
1) Whether we need have the cmem->ranges[] partly changed, or keep it
unchanged when OOB happened. Previously discussed link:[1].
2) Set cmem->max_nr_ranges in crash_setup_memmap_entries() to 1 or 2.
Previously discussed link:[2].
3) To enhance crash_setup_memmap_entries() readability, how to move
code. Previously discussed link:[2].
v2:
- Fix potential out of bounds in crash_setup_memmap_entries().
- Add a comment in fill_up_crash_elf_data() to explain why the array
size do not need to be changed.
v1:
Link: https://lore.kernel.org/all/20231127025641.62210-1-fuqiang.wang@easystack.cn/
[1]: https://lore.kernel.org/all/ZXrY7QbXAlxydsSC@MiWiFi-R3L-srv/
[2]: https://lore.kernel.org/all/273284e8-7680-4f5f-8065-c5d780987e59@easystack.cn/
fuqiang wang (2):
x86/kexec: Fix potential out of bounds in crash_setup_memmap_entries()
kexec: Fix potential out of bounds in crash_exclude_mem_range()
arch/x86/kernel/crash.c | 20 ++++++++++++++------
kernel/crash_core.c | 7 +++----
2 files changed, 17 insertions(+), 10 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v2 1/2] x86/kexec: Fix potential out of bounds in crash_setup_memmap_entries() 2023-12-20 5:57 [PATCH v2 0/2] kexec: fix potential cmem->ranges out of bounds fuqiang wang @ 2023-12-20 5:57 ` fuqiang wang 2023-12-21 13:14 ` Baoquan He 2023-12-20 5:57 ` [PATCH v2 2/2] kexec: Fix potential out of bounds in crash_exclude_mem_range() fuqiang wang 1 sibling, 1 reply; 7+ messages in thread From: fuqiang wang @ 2023-12-20 5:57 UTC (permalink / raw) To: Baoquan He, Vivek Goyal, Dave Young, Yuntao Wang; +Cc: kexec, linux-kernel In memmap_exclude_ranges(), there will exclude elfheader from crashk_res. In the current x86 architecture code, the elfheader is always allocated at crashk_res.start. It seems that there won't be a split a new range. But it depends on the allocation position of elfheader in crashk_res. To avoid potential out of bounds in future, Set the array size to 2. But similar issue will not exist in fill_up_crash_elf_data(). Because the range to be excluded is [0, 1M], start (0) is special and will not appear in the middle of existing cmem->ranges[]. I added a comment to explain it. Signed-off-by: fuqiang wang <fuqiang.wang@easystack.cn> --- arch/x86/kernel/crash.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index c92d88680dbf..1c15d0884c90 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -149,6 +149,13 @@ static struct crash_mem *fill_up_crash_elf_data(void) /* * Exclusion of crash region and/or crashk_low_res may cause * another range split. So add extra two slots here. + * + * Exclusion of low 1M may not cause another range split, because the + * range of exclude is [0, 1M] and the condition for splitting a new + * region is that the start, end parameters are both in a certain + * existing region in cmem and cannot be equal to existing region's + * start or end. Obviously, the start of [0, 1M] cannot meet this + * condition. */ nr_ranges += 2; cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); @@ -282,9 +289,15 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) struct crash_memmap_data cmd; struct crash_mem *cmem; - cmem = vzalloc(struct_size(cmem, ranges, 1)); + cmem = vzalloc(struct_size(cmem, ranges, 2)); if (!cmem) return -ENOMEM; + cmem->max_nr_ranges = 2; + + /* Exclude some ranges from crashk_res and add rest to memmap */ + ret = memmap_exclude_ranges(image, cmem, crashk_res.start, crashk_res.end); + if (ret) + goto out; memset(&cmd, 0, sizeof(struct crash_memmap_data)); cmd.params = params; @@ -320,11 +333,6 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) add_e820_entry(params, &ei); } - /* Exclude some ranges from crashk_res and add rest to memmap */ - ret = memmap_exclude_ranges(image, cmem, crashk_res.start, crashk_res.end); - if (ret) - goto out; - for (i = 0; i < cmem->nr_ranges; i++) { ei.size = cmem->ranges[i].end - cmem->ranges[i].start + 1; -- 2.42.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] x86/kexec: Fix potential out of bounds in crash_setup_memmap_entries() 2023-12-20 5:57 ` [PATCH v2 1/2] x86/kexec: Fix potential out of bounds in crash_setup_memmap_entries() fuqiang wang @ 2023-12-21 13:14 ` Baoquan He 2023-12-22 11:41 ` fuqiang wang 0 siblings, 1 reply; 7+ messages in thread From: Baoquan He @ 2023-12-21 13:14 UTC (permalink / raw) To: fuqiang wang; +Cc: Vivek Goyal, Dave Young, Yuntao Wang, kexec, linux-kernel On 12/20/23 at 01:57pm, fuqiang wang wrote: > In memmap_exclude_ranges(), there will exclude elfheader from > crashk_res. In the current x86 architecture code, the elfheader is > always allocated at crashk_res.start. It seems that there won't be a > split a new range. But it depends on the allocation position of > elfheader in crashk_res. To avoid potential out of bounds in future, Set > the array size to 2. If so, I would suggest to add extra slot for low 1M too in fill_up_crash_elf_data() lest the low 1M could be changed in the future, e.g [start, 1M]. > > But similar issue will not exist in fill_up_crash_elf_data(). Because > the range to be excluded is [0, 1M], start (0) is special and will not > appear in the middle of existing cmem->ranges[]. I added a comment to > explain it. > > Signed-off-by: fuqiang wang <fuqiang.wang@easystack.cn> > --- > arch/x86/kernel/crash.c | 20 ++++++++++++++------ > 1 file changed, 14 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c > index c92d88680dbf..1c15d0884c90 100644 > --- a/arch/x86/kernel/crash.c > +++ b/arch/x86/kernel/crash.c > @@ -149,6 +149,13 @@ static struct crash_mem *fill_up_crash_elf_data(void) > /* > * Exclusion of crash region and/or crashk_low_res may cause > * another range split. So add extra two slots here. > + * > + * Exclusion of low 1M may not cause another range split, because the > + * range of exclude is [0, 1M] and the condition for splitting a new > + * region is that the start, end parameters are both in a certain > + * existing region in cmem and cannot be equal to existing region's > + * start or end. Obviously, the start of [0, 1M] cannot meet this > + * condition. > */ > nr_ranges += 2; > cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); > @@ -282,9 +289,15 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) > struct crash_memmap_data cmd; > struct crash_mem *cmem; > > - cmem = vzalloc(struct_size(cmem, ranges, 1)); > + cmem = vzalloc(struct_size(cmem, ranges, 2)); > if (!cmem) > return -ENOMEM; > + cmem->max_nr_ranges = 2; > + > + /* Exclude some ranges from crashk_res and add rest to memmap */ > + ret = memmap_exclude_ranges(image, cmem, crashk_res.start, crashk_res.end); > + if (ret) > + goto out; > > memset(&cmd, 0, sizeof(struct crash_memmap_data)); > cmd.params = params; > @@ -320,11 +333,6 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) > add_e820_entry(params, &ei); > } > > - /* Exclude some ranges from crashk_res and add rest to memmap */ > - ret = memmap_exclude_ranges(image, cmem, crashk_res.start, crashk_res.end); > - if (ret) > - goto out; And you didn't mention moving above code block up in log. I would suggest keeping it as is because it looks more reasonable to be adjacent to the following cmem->ranges[] handling. > - > for (i = 0; i < cmem->nr_ranges; i++) { > ei.size = cmem->ranges[i].end - cmem->ranges[i].start + 1; > > -- > 2.42.0 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] x86/kexec: Fix potential out of bounds in crash_setup_memmap_entries() 2023-12-21 13:14 ` Baoquan He @ 2023-12-22 11:41 ` fuqiang wang 0 siblings, 0 replies; 7+ messages in thread From: fuqiang wang @ 2023-12-22 11:41 UTC (permalink / raw) To: Baoquan He; +Cc: Vivek Goyal, Dave Young, Yuntao Wang, kexec, linux-kernel 在 2023/12/21 21:14, Baoquan He 写道: > On 12/20/23 at 01:57pm, fuqiang wang wrote: >> In memmap_exclude_ranges(), there will exclude elfheader from >> crashk_res. In the current x86 architecture code, the elfheader is >> always allocated at crashk_res.start. It seems that there won't be a >> split a new range. But it depends on the allocation position of >> elfheader in crashk_res. To avoid potential out of bounds in future, Set >> the array size to 2. > If so, I would suggest to add extra slot for low 1M too in > fill_up_crash_elf_data() lest the low 1M could be changed in the future, > e.g [start, 1M]. Hi Baoquan This seems to be better for future maintenance. Thank you for your suggestion. >> But similar issue will not exist in fill_up_crash_elf_data(). Because >> the range to be excluded is [0, 1M], start (0) is special and will not >> appear in the middle of existing cmem->ranges[]. I added a comment to >> explain it. >> >> Signed-off-by: fuqiang wang <fuqiang.wang@easystack.cn> >> --- >> arch/x86/kernel/crash.c | 20 ++++++++++++++------ >> 1 file changed, 14 insertions(+), 6 deletions(-) >> >> diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c >> index c92d88680dbf..1c15d0884c90 100644 >> --- a/arch/x86/kernel/crash.c >> +++ b/arch/x86/kernel/crash.c >> @@ -149,6 +149,13 @@ static struct crash_mem *fill_up_crash_elf_data(void) >> /* >> * Exclusion of crash region and/or crashk_low_res may cause >> * another range split. So add extra two slots here. >> + * >> + * Exclusion of low 1M may not cause another range split, because the >> + * range of exclude is [0, 1M] and the condition for splitting a new >> + * region is that the start, end parameters are both in a certain >> + * existing region in cmem and cannot be equal to existing region's >> + * start or end. Obviously, the start of [0, 1M] cannot meet this >> + * condition. >> */ >> nr_ranges += 2; >> cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); >> @@ -282,9 +289,15 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) >> struct crash_memmap_data cmd; >> struct crash_mem *cmem; >> >> - cmem = vzalloc(struct_size(cmem, ranges, 1)); >> + cmem = vzalloc(struct_size(cmem, ranges, 2)); >> if (!cmem) >> return -ENOMEM; >> + cmem->max_nr_ranges = 2; >> + >> + /* Exclude some ranges from crashk_res and add rest to memmap */ >> + ret = memmap_exclude_ranges(image, cmem, crashk_res.start, crashk_res.end); >> + if (ret) >> + goto out; >> >> memset(&cmd, 0, sizeof(struct crash_memmap_data)); >> cmd.params = params; >> @@ -320,11 +333,6 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) >> add_e820_entry(params, &ei); >> } >> >> - /* Exclude some ranges from crashk_res and add rest to memmap */ >> - ret = memmap_exclude_ranges(image, cmem, crashk_res.start, crashk_res.end); >> - if (ret) >> - goto out; > And you didn't mention moving above code block up in log. I would > suggest keeping it as is because it looks more reasonable to be adjacent > to the following cmem->ranges[] handling. Yes, baoquan, keeping it as it is may be more coherent.I will post a new patch later. Thanks fuqiang >> - >> for (i = 0; i < cmem->nr_ranges; i++) { >> ei.size = cmem->ranges[i].end - cmem->ranges[i].start + 1; >> >> -- >> 2.42.0 >> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] kexec: Fix potential out of bounds in crash_exclude_mem_range() 2023-12-20 5:57 [PATCH v2 0/2] kexec: fix potential cmem->ranges out of bounds fuqiang wang 2023-12-20 5:57 ` [PATCH v2 1/2] x86/kexec: Fix potential out of bounds in crash_setup_memmap_entries() fuqiang wang @ 2023-12-20 5:57 ` fuqiang wang 2023-12-21 11:42 ` Baoquan He 1 sibling, 1 reply; 7+ messages in thread From: fuqiang wang @ 2023-12-20 5:57 UTC (permalink / raw) To: Baoquan He, Vivek Goyal, Dave Young, Yuntao Wang; +Cc: kexec, linux-kernel When the split does not occur on the last array member, the current code will not return an error. So the correct array out-of-bounds check should be mem->nr_ranges >= mem->max_nr_ranges. When the OOB happen, the cmem->ranges[] have changed, so return early to avoid it. Signed-off-by: fuqiang wang <fuqiang.wang@easystack.cn> --- kernel/crash_core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/kernel/crash_core.c b/kernel/crash_core.c index d4313b53837e..b1ab61c74fd2 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -611,6 +611,9 @@ int crash_exclude_mem_range(struct crash_mem *mem, } if (p_start > start && p_end < end) { + /* Split happened */ + if (mem->nr_ranges >= mem->max_nr_ranges) + return -ENOMEM; /* Split original range */ mem->ranges[i].end = p_start - 1; temp_range.start = p_end + 1; @@ -626,10 +629,6 @@ int crash_exclude_mem_range(struct crash_mem *mem, if (!temp_range.end) return 0; - /* Split happened */ - if (i == mem->max_nr_ranges - 1) - return -ENOMEM; - /* Location where new range should go */ j = i + 1; if (j < mem->nr_ranges) { -- 2.42.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] kexec: Fix potential out of bounds in crash_exclude_mem_range() 2023-12-20 5:57 ` [PATCH v2 2/2] kexec: Fix potential out of bounds in crash_exclude_mem_range() fuqiang wang @ 2023-12-21 11:42 ` Baoquan He 2023-12-22 11:08 ` fuqiang wang 0 siblings, 1 reply; 7+ messages in thread From: Baoquan He @ 2023-12-21 11:42 UTC (permalink / raw) To: fuqiang wang; +Cc: Vivek Goyal, Dave Young, Yuntao Wang, kexec, linux-kernel On 12/20/23 at 01:57pm, fuqiang wang wrote: > When the split does not occur on the last array member, the current code > will not return an error. So the correct array out-of-bounds check should > be mem->nr_ranges >= mem->max_nr_ranges. > > When the OOB happen, the cmem->ranges[] have changed, so return early to > avoid it. > > Signed-off-by: fuqiang wang <fuqiang.wang@easystack.cn> > --- > kernel/crash_core.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) You may need rebase your work on next/master branch to avoid conflict. https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git In the current, below commit exists, then code change in this patch may not be needed. 86d80cbb61ca crash_core: fix and simplify the logic of crash_exclude_mem_range() > > diff --git a/kernel/crash_core.c b/kernel/crash_core.c > index d4313b53837e..b1ab61c74fd2 100644 > --- a/kernel/crash_core.c > +++ b/kernel/crash_core.c > @@ -611,6 +611,9 @@ int crash_exclude_mem_range(struct crash_mem *mem, > } > > if (p_start > start && p_end < end) { > + /* Split happened */ > + if (mem->nr_ranges >= mem->max_nr_ranges) > + return -ENOMEM; > /* Split original range */ > mem->ranges[i].end = p_start - 1; > temp_range.start = p_end + 1; > @@ -626,10 +629,6 @@ int crash_exclude_mem_range(struct crash_mem *mem, > if (!temp_range.end) > return 0; > > - /* Split happened */ > - if (i == mem->max_nr_ranges - 1) > - return -ENOMEM; > - > /* Location where new range should go */ > j = i + 1; > if (j < mem->nr_ranges) { > -- > 2.42.0 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] kexec: Fix potential out of bounds in crash_exclude_mem_range() 2023-12-21 11:42 ` Baoquan He @ 2023-12-22 11:08 ` fuqiang wang 0 siblings, 0 replies; 7+ messages in thread From: fuqiang wang @ 2023-12-22 11:08 UTC (permalink / raw) To: Baoquan He; +Cc: Vivek Goyal, Dave Young, Yuntao Wang, kexec, linux-kernel 在 2023/12/21 19:42, Baoquan He 写道: > You may need rebase your work on next/master branch to avoid conflict. > > https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git > > In the current, below commit exists, then code change in this patch may > not be needed. > 86d80cbb61ca crash_core: fix and simplify the logic of crash_exclude_mem_range() > Yes, Baoquan, you are right. It's my mistake. Thank you very much ~ ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-12-22 12:21 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-12-20 5:57 [PATCH v2 0/2] kexec: fix potential cmem->ranges out of bounds fuqiang wang 2023-12-20 5:57 ` [PATCH v2 1/2] x86/kexec: Fix potential out of bounds in crash_setup_memmap_entries() fuqiang wang 2023-12-21 13:14 ` Baoquan He 2023-12-22 11:41 ` fuqiang wang 2023-12-20 5:57 ` [PATCH v2 2/2] kexec: Fix potential out of bounds in crash_exclude_mem_range() fuqiang wang 2023-12-21 11:42 ` Baoquan He 2023-12-22 11:08 ` fuqiang wang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox