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 appropriately sized as a struct nd_cmd_pkg. This can lead > to out-of-bounds access and undefined behavior if the buffer does not > have sufficient space. > > To address this, a check was added in acpi_nfit_ctl() to ensure that > buf is not NULL and that buf_len is less than sizeof(*call_pkg) > before accessing it. This ensures safe access to the members of > call_pkg, including the nd_reserved2 array. > > Reported-by: syzbot+7534f060ebda6b8b51b3@xxxxxxxxxxxxxxxxxxxxxxxxx > Closes: https://syzkaller.appspot.com/bug?extid=7534f060ebda6b8b51b3 > Tested-by: syzbot+7534f060ebda6b8b51b3@xxxxxxxxxxxxxxxxxxxxxxxxx > Fixes: ebe9f6f19d80 ("acpi/nfit: Fix bus command validation") > Signed-off-by: Suraj Sonawane <surajsonawane0215@xxxxxxxxx> > --- > V1: https://lore.kernel.org/lkml/20241111080429.9861-1-surajsonawane0215@xxxxxxxxx/ > V2: Initialized `out_obj` to `NULL` in `acpi_nfit_ctl()` to prevent > potential uninitialized variable usage if condition is true. > V3: Changed the condition to if (!buf || buf_len < sizeof(*call_pkg)) > and updated the Fixes tag to reference the correct commit. > V4: Removed the explicit cast to maintain the original code style. > V5: Re-Initialized `out_obj` to NULL. To prevent > potential uninitialized variable usage if condition is true. > > drivers/acpi/nfit/core.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c > index 5429ec9ef..573ed264c 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; This is not needed... > const struct nd_cmd_desc *desc = NULL; > struct device *dev = acpi_desc->dev; > struct nd_cmd_pkg *call_pkg = NULL; > @@ -454,8 +454,15 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, > if (cmd_rc) > *cmd_rc = -EINVAL; > > - if (cmd == ND_CMD_CALL) > + if (cmd == ND_CMD_CALL) { > + if (!buf || buf_len < sizeof(*call_pkg)) { > + rc = -EINVAL; > + goto out; Just return -EINVAL. Ira > + } > + > call_pkg = buf; > + } > + > func = cmd_to_func(nfit_mem, cmd, call_pkg, &family); > if (func < 0) > return func; > -- > 2.34.1 >