Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: NFIT: Fix input validation of bus-family

Dan reports that smatch thinks userspace can craft an out-of-bound bus
family number. However, nd_cmd_clear_to_send() blocks all non-zero
values of bus-family since only the kernel can initiate these commands.
However, in the speculation path, family is a user controlled array
index value so mask it for speculation safety. Also, since the
nd_cmd_clear_to_send() safety is non-obvious and possibly may change in
the future include input validation as if userspace could get past the
nd_cmd_clear_to_send() gatekeeper.

Link: http://lore.kernel.org/r/20201111113000.GA1237157@mwanda
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Fixes: 6450ddbd5d8e ("ACPI: NFIT: Define runtime firmware activation commands")
Cc: <stable@vger.kernel.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

+5 -1
+5 -1
drivers/acpi/nfit/core.c
··· 5 5 #include <linux/list_sort.h> 6 6 #include <linux/libnvdimm.h> 7 7 #include <linux/module.h> 8 + #include <linux/nospec.h> 8 9 #include <linux/mutex.h> 9 10 #include <linux/ndctl.h> 10 11 #include <linux/sysfs.h> ··· 480 479 cmd_mask = nd_desc->cmd_mask; 481 480 if (cmd == ND_CMD_CALL && call_pkg->nd_family) { 482 481 family = call_pkg->nd_family; 483 - if (!test_bit(family, &nd_desc->bus_family_mask)) 482 + if (family > NVDIMM_BUS_FAMILY_MAX || 483 + !test_bit(family, &nd_desc->bus_family_mask)) 484 484 return -EINVAL; 485 + family = array_index_nospec(family, 486 + NVDIMM_BUS_FAMILY_MAX + 1); 485 487 dsm_mask = acpi_desc->family_dsm_mask[family]; 486 488 guid = to_nfit_bus_uuid(family); 487 489 } else {