2019-02-08 00:12:21

by Dan Williams

[permalink] [raw]
Subject: [PATCH] acpi/nfit: Fix bus command validation

Commit 11189c1089da "acpi/nfit: Fix command-supported detection" broke
ND_CMD_CALL for bus-level commands. The "func = cmd" assumption is only
valid for:

ND_CMD_ARS_CAP
ND_CMD_ARS_START
ND_CMD_ARS_STATUS
ND_CMD_CLEAR_ERROR

The function number otherwise needs to be pulled from the command
payload for:

NFIT_CMD_TRANSLATE_SPA
NFIT_CMD_ARS_INJECT_SET
NFIT_CMD_ARS_INJECT_CLEAR
NFIT_CMD_ARS_INJECT_GET

Update cmd_to_func() for the bus case and call it in the common path.

Fixes: 11189c1089da ("acpi/nfit: Fix command-supported detection")
Cc: <[email protected]>
Cc: Vishal Verma <[email protected]>
Reported-by: Grzegorz Burzynski <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
drivers/acpi/nfit/core.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index e18ade5d74e9..c34c595d6bb0 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -415,7 +415,7 @@ static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
if (call_pkg) {
int i;

- if (nfit_mem->family != call_pkg->nd_family)
+ if (nfit_mem && nfit_mem->family != call_pkg->nd_family)
return -ENOTTY;

for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
@@ -424,6 +424,10 @@ static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
return call_pkg->nd_command;
}

+ /* In the !call_pkg case, bus commands == bus functions */
+ if (!nfit_mem)
+ return cmd;
+
/* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
return cmd;
@@ -454,17 +458,18 @@ 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;
+ func = cmd_to_func(nfit_mem, cmd, call_pkg);
+ if (func < 0)
+ return func;
+
if (nvdimm) {
struct acpi_device *adev = nfit_mem->adev;

if (!adev)
return -ENOTTY;

- if (cmd == ND_CMD_CALL)
- call_pkg = buf;
- func = cmd_to_func(nfit_mem, cmd, call_pkg);
- if (func < 0)
- return func;
dimm_name = nvdimm_name(nvdimm);
cmd_name = nvdimm_cmd_name(cmd);
cmd_mask = nvdimm_cmd_mask(nvdimm);
@@ -475,12 +480,9 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
} else {
struct acpi_device *adev = to_acpi_dev(acpi_desc);

- func = cmd;
cmd_name = nvdimm_bus_cmd_name(cmd);
cmd_mask = nd_desc->cmd_mask;
- dsm_mask = cmd_mask;
- if (cmd == ND_CMD_CALL)
- dsm_mask = nd_desc->bus_dsm_mask;
+ dsm_mask = nd_desc->bus_dsm_mask;
desc = nd_cmd_bus_desc(cmd);
guid = to_nfit_uuid(NFIT_DEV_BUS);
handle = adev->handle;



2019-02-08 00:42:03

by Vishal Verma

[permalink] [raw]
Subject: Re: [PATCH] acpi/nfit: Fix bus command validation


On Thu, 2019-02-07 at 15:57 -0800, Dan Williams wrote:
> Commit 11189c1089da "acpi/nfit: Fix command-supported detection" broke
> ND_CMD_CALL for bus-level commands. The "func = cmd" assumption is only
> valid for:
>
> ND_CMD_ARS_CAP
> ND_CMD_ARS_START
> ND_CMD_ARS_STATUS
> ND_CMD_CLEAR_ERROR
>
> The function number otherwise needs to be pulled from the command
> payload for:
>
> NFIT_CMD_TRANSLATE_SPA
> NFIT_CMD_ARS_INJECT_SET
> NFIT_CMD_ARS_INJECT_CLEAR
> NFIT_CMD_ARS_INJECT_GET
>
> Update cmd_to_func() for the bus case and call it in the common path.
>
> Fixes: 11189c1089da ("acpi/nfit: Fix command-supported detection")
> Cc: <[email protected]>
> Cc: Vishal Verma <[email protected]>
> Reported-by: Grzegorz Burzynski <[email protected]>
> Signed-off-by: Dan Williams <[email protected]>
> ---
> drivers/acpi/nfit/core.c | 22 ++++++++++++----------
> 1 file changed, 12 insertions(+), 10 deletions(-)

Looks good,
Reviewed-by: Vishal Verma <[email protected]>

2019-02-20 01:57:29

by Jeff Moyer

[permalink] [raw]
Subject: Re: [PATCH] acpi/nfit: Fix bus command validation

Dan Williams <[email protected]> writes:

> Commit 11189c1089da "acpi/nfit: Fix command-supported detection" broke
> ND_CMD_CALL for bus-level commands. The "func = cmd" assumption is only
> valid for:
>
> ND_CMD_ARS_CAP
> ND_CMD_ARS_START
> ND_CMD_ARS_STATUS
> ND_CMD_CLEAR_ERROR
>
> The function number otherwise needs to be pulled from the command
> payload for:
>
> NFIT_CMD_TRANSLATE_SPA
> NFIT_CMD_ARS_INJECT_SET
> NFIT_CMD_ARS_INJECT_CLEAR
> NFIT_CMD_ARS_INJECT_GET
>
> Update cmd_to_func() for the bus case and call it in the common path.
>
> Fixes: 11189c1089da ("acpi/nfit: Fix command-supported detection")
> Cc: <[email protected]>
> Cc: Vishal Verma <[email protected]>
> Reported-by: Grzegorz Burzynski <[email protected]>
> Signed-off-by: Dan Williams <[email protected]>

Tricky code path, eh?

Tested-by: Jeff Moyer <[email protected]>

-Jeff

> ---
> drivers/acpi/nfit/core.c | 22 ++++++++++++----------
> 1 file changed, 12 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
> index e18ade5d74e9..c34c595d6bb0 100644
> --- a/drivers/acpi/nfit/core.c
> +++ b/drivers/acpi/nfit/core.c
> @@ -415,7 +415,7 @@ static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
> if (call_pkg) {
> int i;
>
> - if (nfit_mem->family != call_pkg->nd_family)
> + if (nfit_mem && nfit_mem->family != call_pkg->nd_family)
> return -ENOTTY;
>
> for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
> @@ -424,6 +424,10 @@ static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
> return call_pkg->nd_command;
> }
>
> + /* In the !call_pkg case, bus commands == bus functions */
> + if (!nfit_mem)
> + return cmd;
> +
> /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
> if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
> return cmd;
> @@ -454,17 +458,18 @@ 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;
> + func = cmd_to_func(nfit_mem, cmd, call_pkg);
> + if (func < 0)
> + return func;
> +
> if (nvdimm) {
> struct acpi_device *adev = nfit_mem->adev;
>
> if (!adev)
> return -ENOTTY;
>
> - if (cmd == ND_CMD_CALL)
> - call_pkg = buf;
> - func = cmd_to_func(nfit_mem, cmd, call_pkg);
> - if (func < 0)
> - return func;
> dimm_name = nvdimm_name(nvdimm);
> cmd_name = nvdimm_cmd_name(cmd);
> cmd_mask = nvdimm_cmd_mask(nvdimm);
> @@ -475,12 +480,9 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
> } else {
> struct acpi_device *adev = to_acpi_dev(acpi_desc);
>
> - func = cmd;
> cmd_name = nvdimm_bus_cmd_name(cmd);
> cmd_mask = nd_desc->cmd_mask;
> - dsm_mask = cmd_mask;
> - if (cmd == ND_CMD_CALL)
> - dsm_mask = nd_desc->bus_dsm_mask;
> + dsm_mask = nd_desc->bus_dsm_mask;
> desc = nd_cmd_bus_desc(cmd);
> guid = to_nfit_uuid(NFIT_DEV_BUS);
> handle = adev->handle;
>
> _______________________________________________
> Linux-nvdimm mailing list
> [email protected]
> https://lists.01.org/mailman/listinfo/linux-nvdimm

2019-02-20 02:59:40

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH] acpi/nfit: Fix bus command validation

On Tue, Feb 19, 2019 at 5:57 PM Jeff Moyer <[email protected]> wrote:
>
> Dan Williams <[email protected]> writes:
>
> > Commit 11189c1089da "acpi/nfit: Fix command-supported detection" broke
> > ND_CMD_CALL for bus-level commands. The "func = cmd" assumption is only
> > valid for:
> >
> > ND_CMD_ARS_CAP
> > ND_CMD_ARS_START
> > ND_CMD_ARS_STATUS
> > ND_CMD_CLEAR_ERROR
> >
> > The function number otherwise needs to be pulled from the command
> > payload for:
> >
> > NFIT_CMD_TRANSLATE_SPA
> > NFIT_CMD_ARS_INJECT_SET
> > NFIT_CMD_ARS_INJECT_CLEAR
> > NFIT_CMD_ARS_INJECT_GET
> >
> > Update cmd_to_func() for the bus case and call it in the common path.
> >
> > Fixes: 11189c1089da ("acpi/nfit: Fix command-supported detection")
> > Cc: <[email protected]>
> > Cc: Vishal Verma <[email protected]>
> > Reported-by: Grzegorz Burzynski <[email protected]>
> > Signed-off-by: Dan Williams <[email protected]>
>
> Tricky code path, eh?

ioctl path, number one source of bugs / thrash in this subsystem. 2nd
place, ARS.

> Tested-by: Jeff Moyer <[email protected]>

Thanks.

2019-02-20 08:30:25

by Johannes Thumshirn

[permalink] [raw]
Subject: Re: [PATCH] acpi/nfit: Fix bus command validation

On 20/02/2019 03:58, Dan Williams wrote:
[...]

>>
>> Tricky code path, eh?
>
> ioctl path, number one source of bugs / thrash in this subsystem. 2nd
> place, ARS.

Possibly unpopular idea, but should we maybe teach trinity/syzcaller
about these ioctl()s?

Better we find the bugs in a QA like environment than in the filed, I guess?

Byte,
Johannes
--
Johannes Thumshirn SUSE Labs Filesystems
[email protected] +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

2019-02-20 16:16:48

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH] acpi/nfit: Fix bus command validation

On Wed, Feb 20, 2019 at 12:30 AM Johannes Thumshirn <[email protected]> wrote:
>
> On 20/02/2019 03:58, Dan Williams wrote:
> [...]
>
> >>
> >> Tricky code path, eh?
> >
> > ioctl path, number one source of bugs / thrash in this subsystem. 2nd
> > place, ARS.
>
> Possibly unpopular idea, but should we maybe teach trinity/syzcaller
> about these ioctl()s?
>
> Better we find the bugs in a QA like environment than in the filed, I guess?

I wouldn't be opposed to syzkaller fuzzing the nvdimm-ioctl path.

2019-02-20 17:23:47

by Johannes Thumshirn

[permalink] [raw]
Subject: Re: [PATCH] acpi/nfit: Fix bus command validation

On 20/02/2019 17:15, Dan Williams wrote:> I wouldn't be opposed to
syzkaller fuzzing the nvdimm-ioctl path.
As a heads up, I've started adding the ioctl() definitions to syzcaller.
Just so we don't duplicate any efforts.

Byte,
Johannes
--
Johannes Thumshirn SUSE Labs Filesystems
[email protected] +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

2019-02-21 13:29:13

by Johannes Thumshirn

[permalink] [raw]
Subject: Re: [PATCH] acpi/nfit: Fix bus command validation

[+CC dvyukov ]

On 20/02/2019 18:21, Johannes Thumshirn wrote:
> On 20/02/2019 17:15, Dan Williams wrote:> I wouldn't be opposed to
> syzkaller fuzzing the nvdimm-ioctl path.
> As a heads up, I've started adding the ioctl() definitions to syzcaller.
> Just so we don't duplicate any efforts.

So AFAICS this (see attachment) should do the trick.

@dvyukov is there something I'm missing, or can syzkaller pick up the
/dev/ndctl devices and start fuzzing the ioctl path with this?

Thanks,
Johannes
--
Johannes Thumshirn SUSE Labs Filesystems
[email protected] +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850


Attachments:
dev_ndctl.txt (3.02 kB)