Message ID | 20241112052035.14122-1-surajsonawane0215@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | [v2] acpi: nfit: vmalloc-out-of-bounds Read in acpi_nfit_ctl | expand |
On Tue, Nov 12, 2024 at 10:50:35AM +0530, Suraj Sonawane wrote: > Fix an issue detected by syzbot with KASAN: > > BUG: KASAN: vmalloc-out-of-bounds in cmd_to_func drivers/acpi/nfit/ > core.c:416 [inline] > BUG: KASAN: vmalloc-out-of-bounds in acpi_nfit_ctl+0x20e8/0x24a0 > drivers/acpi/nfit/core.c:459 > > The issue occurs in `cmd_to_func` when the `call_pkg->nd_reserved2` > array is accessed without verifying that `call_pkg` points to a > buffer that is sized appropriately as a `struct nd_cmd_pkg`. This > could lead to out-of-bounds access and undefined behavior if the > buffer does not have sufficient space. > > To address this issue, a check was added in `acpi_nfit_ctl()` to > ensure that `buf` is not `NULL` and `buf_len` is greater than or > equal to `sizeof(struct nd_cmd_pkg)` before casting `buf` to > `struct nd_cmd_pkg *`. This ensures safe access to the members of > `call_pkg`, including the `nd_reserved2` array. That all sounds good! A couple of coding conventions fixups suggested below - snip > @@ -439,7 +439,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, > { > struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); > struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); > - union acpi_object in_obj, in_buf, *out_obj; > + union acpi_object in_obj, in_buf, *out_obj = NULL; > const struct nd_cmd_desc *desc = NULL; > struct device *dev = acpi_desc->dev; > struct nd_cmd_pkg *call_pkg = NULL; > @@ -454,8 +454,14 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, > if (cmd_rc) > *cmd_rc = -EINVAL; > > - if (cmd == ND_CMD_CALL) > - call_pkg = buf; > + if (cmd == ND_CMD_CALL) { > + if (buf == NULL || buf_len < sizeof(struct nd_cmd_pkg)) { Comparison to NULL and sizeof() usage preferred like this: if (!buf || buf_len < sizeof(*call_pkg)) -snip > >
On Tue, Nov 12, 2024 at 10:50:35AM +0530, Suraj Sonawane wrote: > Fix an issue detected by syzbot with KASAN: > > BUG: KASAN: vmalloc-out-of-bounds in cmd_to_func drivers/acpi/nfit/ > core.c:416 [inline] > BUG: KASAN: vmalloc-out-of-bounds in acpi_nfit_ctl+0x20e8/0x24a0 > drivers/acpi/nfit/core.c:459 > > The issue occurs in `cmd_to_func` when the `call_pkg->nd_reserved2` > array is accessed without verifying that `call_pkg` points to a > buffer that is sized appropriately as a `struct nd_cmd_pkg`. This > could lead to out-of-bounds access and undefined behavior if the > buffer does not have sufficient space. > > To address this issue, a check was added in `acpi_nfit_ctl()` to > ensure that `buf` is not `NULL` and `buf_len` is greater than or > equal to `sizeof(struct nd_cmd_pkg)` before casting `buf` to > `struct nd_cmd_pkg *`. This ensures safe access to the members of > `call_pkg`, including the `nd_reserved2` array. > > This change preventing out-of-bounds reads. > > Reported-by: syzbot+7534f060ebda6b8b51b3@syzkaller.appspotmail.com > Closes: https://syzkaller.appspot.com/bug?extid=7534f060ebda6b8b51b3 > Tested-by: syzbot+7534f060ebda6b8b51b3@syzkaller.appspotmail.com > Fixes: 2d5404caa8c7 ("Linux 6.12-rc7") > Signed-off-by: Suraj Sonawane <surajsonawane0215@gmail.com> Suraj, The fixes tag needs to be where the issue originated, not where you discovered it (which I'm guessing was using 6.12-rc7). Here's how I find the tag: $ git blame drivers/acpi/nfit/core.c | grep call_pkg | grep buf ebe9f6f19d80d drivers/acpi/nfit/core.c (Dan Williams 2019-02-07 14:56:50 -0800 458) call_pkg = buf; $ git log -1 --pretty=fixes ebe9f6f19d80d Fixes: ebe9f6f19d80 ("acpi/nfit: Fix bus command validation") I think ^ should be your Fixes tag. snip >
On 13/11/24 10:08, Alison Schofield wrote: > On Tue, Nov 12, 2024 at 10:50:35AM +0530, Suraj Sonawane wrote: >> Fix an issue detected by syzbot with KASAN: >> >> BUG: KASAN: vmalloc-out-of-bounds in cmd_to_func drivers/acpi/nfit/ >> core.c:416 [inline] >> BUG: KASAN: vmalloc-out-of-bounds in acpi_nfit_ctl+0x20e8/0x24a0 >> drivers/acpi/nfit/core.c:459 >> >> The issue occurs in `cmd_to_func` when the `call_pkg->nd_reserved2` >> array is accessed without verifying that `call_pkg` points to a >> buffer that is sized appropriately as a `struct nd_cmd_pkg`. This >> could lead to out-of-bounds access and undefined behavior if the >> buffer does not have sufficient space. >> >> To address this issue, a check was added in `acpi_nfit_ctl()` to >> ensure that `buf` is not `NULL` and `buf_len` is greater than or >> equal to `sizeof(struct nd_cmd_pkg)` before casting `buf` to >> `struct nd_cmd_pkg *`. This ensures safe access to the members of >> `call_pkg`, including the `nd_reserved2` array. > > That all sounds good! A couple of coding conventions fixups suggested > below - > > snip > >> @@ -439,7 +439,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, >> { >> struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); >> struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); >> - union acpi_object in_obj, in_buf, *out_obj; >> + union acpi_object in_obj, in_buf, *out_obj = NULL; >> const struct nd_cmd_desc *desc = NULL; >> struct device *dev = acpi_desc->dev; >> struct nd_cmd_pkg *call_pkg = NULL; >> @@ -454,8 +454,14 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, >> if (cmd_rc) >> *cmd_rc = -EINVAL; >> >> - if (cmd == ND_CMD_CALL) >> - call_pkg = buf; >> + if (cmd == ND_CMD_CALL) { >> + if (buf == NULL || buf_len < sizeof(struct nd_cmd_pkg)) { > > Comparison to NULL and sizeof() usage preferred like this: > if (!buf || buf_len < sizeof(*call_pkg)) > > > -snip >> >> Thank you for the feedback and your time. I appreciate your review and coding convention insights. I have studied the suggested change and updated the patch. I will test the updated patch with syzbot and submit a new version very shortly. Best regards, Suraj Sonawane
On 13/11/24 10:21, Alison Schofield wrote: > On Tue, Nov 12, 2024 at 10:50:35AM +0530, Suraj Sonawane wrote: >> Fix an issue detected by syzbot with KASAN: >> >> BUG: KASAN: vmalloc-out-of-bounds in cmd_to_func drivers/acpi/nfit/ >> core.c:416 [inline] >> BUG: KASAN: vmalloc-out-of-bounds in acpi_nfit_ctl+0x20e8/0x24a0 >> drivers/acpi/nfit/core.c:459 >> >> The issue occurs in `cmd_to_func` when the `call_pkg->nd_reserved2` >> array is accessed without verifying that `call_pkg` points to a >> buffer that is sized appropriately as a `struct nd_cmd_pkg`. This >> could lead to out-of-bounds access and undefined behavior if the >> buffer does not have sufficient space. >> >> To address this issue, a check was added in `acpi_nfit_ctl()` to >> ensure that `buf` is not `NULL` and `buf_len` is greater than or >> equal to `sizeof(struct nd_cmd_pkg)` before casting `buf` to >> `struct nd_cmd_pkg *`. This ensures safe access to the members of >> `call_pkg`, including the `nd_reserved2` array. >> >> This change preventing out-of-bounds reads. >> >> Reported-by: syzbot+7534f060ebda6b8b51b3@syzkaller.appspotmail.com >> Closes: https://syzkaller.appspot.com/bug?extid=7534f060ebda6b8b51b3 >> Tested-by: syzbot+7534f060ebda6b8b51b3@syzkaller.appspotmail.com >> Fixes: 2d5404caa8c7 ("Linux 6.12-rc7") >> Signed-off-by: Suraj Sonawane <surajsonawane0215@gmail.com> > > Suraj, > > The fixes tag needs to be where the issue originated, not > where you discovered it (which I'm guessing was using 6.12-rc7). > Thank you for your feedback. > Here's how I find the tag: > > $ git blame drivers/acpi/nfit/core.c | grep call_pkg | grep buf > ebe9f6f19d80d drivers/acpi/nfit/core.c (Dan Williams 2019-02-07 14:56:50 -0800 458) call_pkg = buf; > > $ git log -1 --pretty=fixes ebe9f6f19d80d Thank you for this detailed explaination. > Fixes: ebe9f6f19d80 ("acpi/nfit: Fix bus command validation") > > I think ^ should be your Fixes tag. Yes, I ran the provided steps to verify the commit ID ebe9f6f19d80d and verified it. > > > snip > >> I'll update the Fixes tag in the next version of the patch. Additionally, I will re-test with syzbot and submit the revised patch shortly. Thank you for your time and feedback! Best, Suraj Sonawane
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 5429ec9ef..d0e655a9c 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -439,7 +439,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, { struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); - union acpi_object in_obj, in_buf, *out_obj; + union acpi_object in_obj, in_buf, *out_obj = NULL; const struct nd_cmd_desc *desc = NULL; struct device *dev = acpi_desc->dev; struct nd_cmd_pkg *call_pkg = NULL; @@ -454,8 +454,14 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, if (cmd_rc) *cmd_rc = -EINVAL; - if (cmd == ND_CMD_CALL) - call_pkg = buf; + if (cmd == ND_CMD_CALL) { + if (buf == NULL || buf_len < sizeof(struct nd_cmd_pkg)) { + rc = -EINVAL; + goto out; + } + call_pkg = (struct nd_cmd_pkg *)buf; + } + func = cmd_to_func(nfit_mem, cmd, call_pkg, &family); if (func < 0) return func;