2020-10-26 18:25:12

by Arnd Bergmann

[permalink] [raw]
Subject: [PATCH] firmware: xilinx: fix out-of-bounds access

From: Arnd Bergmann <[email protected]>

The zynqmp_pm_set_suspend_mode() and zynqmp_pm_get_trustzone_version()
functions pass values as api_id into zynqmp_pm_invoke_fn
that are beyond PM_API_MAX, resulting in an out-of-bounds access:

drivers/firmware/xilinx/zynqmp.c: In function 'zynqmp_pm_set_suspend_mode':
drivers/firmware/xilinx/zynqmp.c:150:24: warning: array subscript 2562 is above array bounds of 'u32[64]' {aka 'unsigned int[64]'} [-Warray-bounds]
150 | if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
| ~~~~~~~~~~~~~~~~~~^~~~~~~~
drivers/firmware/xilinx/zynqmp.c:28:12: note: while referencing 'zynqmp_pm_features'
28 | static u32 zynqmp_pm_features[PM_API_MAX];
| ^~~~~~~~~~~~~~~~~~

Replace the resulting undefined behavior with an error return.
This may break some things that happen to work at the moment
but seems better than randomly overwriting kernel data.

I assume we need additional fixes for the two functions that now
return an error.

Fixes: 76582671eb5d ("firmware: xilinx: Add Zynqmp firmware driver")
Fixes: e178df31cf41 ("firmware: xilinx: Implement ZynqMP power management APIs")
Signed-off-by: Arnd Bergmann <[email protected]>
---
drivers/firmware/xilinx/zynqmp.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 8d1ff2454e2e..efb8a66efc68 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -147,6 +147,9 @@ static int zynqmp_pm_feature(u32 api_id)
return 0;

/* Return value if feature is already checked */
+ if (api_id > ARRAY_SIZE(zynqmp_pm_features))
+ return PM_FEATURE_INVALID;
+
if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
return zynqmp_pm_features[api_id];

--
2.27.0


2020-10-27 14:46:21

by Rajan Vaja

[permalink] [raw]
Subject: RE: [PATCH] firmware: xilinx: fix out-of-bounds access

Hi Michal,

> -----Original Message-----
> From: Michal Simek <[email protected]>
> Sent: 27 October 2020 02:53
> To: Arnd Bergmann <[email protected]>; Michal Simek <[email protected]>;
> Rajan Vaja <[email protected]>
> Cc: Arnd Bergmann <[email protected]>; Rajan Vaja <[email protected]>; Greg
> Kroah-Hartman <[email protected]>; Tejas Patel
> <[email protected]>; [email protected]; linux-
> [email protected]; git <[email protected]>
> Subject: Re: [PATCH] firmware: xilinx: fix out-of-bounds access
>
>
>
> On 26. 10. 20 16:54, Arnd Bergmann wrote:
> > From: Arnd Bergmann <[email protected]>
> >
> > The zynqmp_pm_set_suspend_mode() and
> zynqmp_pm_get_trustzone_version()
> > functions pass values as api_id into zynqmp_pm_invoke_fn
> > that are beyond PM_API_MAX, resulting in an out-of-bounds access:
> >
> > drivers/firmware/xilinx/zynqmp.c: In function
> 'zynqmp_pm_set_suspend_mode':
> > drivers/firmware/xilinx/zynqmp.c:150:24: warning: array subscript 2562 is above
> array bounds of 'u32[64]' {aka 'unsigned int[64]'} [-Warray-bounds]
> > 150 | if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
> > | ~~~~~~~~~~~~~~~~~~^~~~~~~~
> > drivers/firmware/xilinx/zynqmp.c:28:12: note: while referencing
> 'zynqmp_pm_features'
> > 28 | static u32 zynqmp_pm_features[PM_API_MAX];
> > | ^~~~~~~~~~~~~~~~~~
>
> Which CONFIG option/tool is reporting this issue?
>
> >
> > Replace the resulting undefined behavior with an error return.
> > This may break some things that happen to work at the moment
> > but seems better than randomly overwriting kernel data.
> >
> > I assume we need additional fixes for the two functions that now
> > return an error.
> >
> > Fixes: 76582671eb5d ("firmware: xilinx: Add Zynqmp firmware driver")
> > Fixes: e178df31cf41 ("firmware: xilinx: Implement ZynqMP power management
> APIs")
> > Signed-off-by: Arnd Bergmann <[email protected]>
> > ---
> > drivers/firmware/xilinx/zynqmp.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/firmware/xilinx/zynqmp.c
> b/drivers/firmware/xilinx/zynqmp.c
> > index 8d1ff2454e2e..efb8a66efc68 100644
> > --- a/drivers/firmware/xilinx/zynqmp.c
> > +++ b/drivers/firmware/xilinx/zynqmp.c
> > @@ -147,6 +147,9 @@ static int zynqmp_pm_feature(u32 api_id)
> > return 0;
> >
> > /* Return value if feature is already checked */
> > + if (api_id > ARRAY_SIZE(zynqmp_pm_features))
> > + return PM_FEATURE_INVALID;
> > +
> > if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
> > return zynqmp_pm_features[api_id];
> >
> >
>
> Definitely good catch but not quite sure what should be correct reaction.
> Rajan: Can you please take a look at it with priority?
[Rajan] Change looks fine to me.

Thanks,
Rajan
>
> Thanks,
> Michal

2020-10-28 06:31:18

by Michal Simek

[permalink] [raw]
Subject: Re: [PATCH] firmware: xilinx: fix out-of-bounds access



On 26. 10. 20 16:54, Arnd Bergmann wrote:
> From: Arnd Bergmann <[email protected]>
>
> The zynqmp_pm_set_suspend_mode() and zynqmp_pm_get_trustzone_version()
> functions pass values as api_id into zynqmp_pm_invoke_fn
> that are beyond PM_API_MAX, resulting in an out-of-bounds access:
>
> drivers/firmware/xilinx/zynqmp.c: In function 'zynqmp_pm_set_suspend_mode':
> drivers/firmware/xilinx/zynqmp.c:150:24: warning: array subscript 2562 is above array bounds of 'u32[64]' {aka 'unsigned int[64]'} [-Warray-bounds]
> 150 | if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
> | ~~~~~~~~~~~~~~~~~~^~~~~~~~
> drivers/firmware/xilinx/zynqmp.c:28:12: note: while referencing 'zynqmp_pm_features'
> 28 | static u32 zynqmp_pm_features[PM_API_MAX];
> | ^~~~~~~~~~~~~~~~~~

Which CONFIG option/tool is reporting this issue?

>
> Replace the resulting undefined behavior with an error return.
> This may break some things that happen to work at the moment
> but seems better than randomly overwriting kernel data.
>
> I assume we need additional fixes for the two functions that now
> return an error.
>
> Fixes: 76582671eb5d ("firmware: xilinx: Add Zynqmp firmware driver")
> Fixes: e178df31cf41 ("firmware: xilinx: Implement ZynqMP power management APIs")
> Signed-off-by: Arnd Bergmann <[email protected]>
> ---
> drivers/firmware/xilinx/zynqmp.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
> index 8d1ff2454e2e..efb8a66efc68 100644
> --- a/drivers/firmware/xilinx/zynqmp.c
> +++ b/drivers/firmware/xilinx/zynqmp.c
> @@ -147,6 +147,9 @@ static int zynqmp_pm_feature(u32 api_id)
> return 0;
>
> /* Return value if feature is already checked */
> + if (api_id > ARRAY_SIZE(zynqmp_pm_features))
> + return PM_FEATURE_INVALID;
> +
> if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
> return zynqmp_pm_features[api_id];
>
>

Definitely good catch but not quite sure what should be correct reaction.
Rajan: Can you please take a look at it with priority?

Thanks,
Michal

2020-10-28 07:30:46

by Michal Simek

[permalink] [raw]
Subject: Re: [PATCH] firmware: xilinx: fix out-of-bounds access



On 27. 10. 20 13:23, Rajan Vaja wrote:
> Hi Michal,
>
>> -----Original Message-----
>> From: Michal Simek <[email protected]>
>> Sent: 27 October 2020 02:53
>> To: Arnd Bergmann <[email protected]>; Michal Simek <[email protected]>;
>> Rajan Vaja <[email protected]>
>> Cc: Arnd Bergmann <[email protected]>; Rajan Vaja <[email protected]>; Greg
>> Kroah-Hartman <[email protected]>; Tejas Patel
>> <[email protected]>; [email protected]; linux-
>> [email protected]; git <[email protected]>
>> Subject: Re: [PATCH] firmware: xilinx: fix out-of-bounds access
>>
>>
>>
>> On 26. 10. 20 16:54, Arnd Bergmann wrote:
>>> From: Arnd Bergmann <[email protected]>
>>>
>>> The zynqmp_pm_set_suspend_mode() and
>> zynqmp_pm_get_trustzone_version()
>>> functions pass values as api_id into zynqmp_pm_invoke_fn
>>> that are beyond PM_API_MAX, resulting in an out-of-bounds access:
>>>
>>> drivers/firmware/xilinx/zynqmp.c: In function
>> 'zynqmp_pm_set_suspend_mode':
>>> drivers/firmware/xilinx/zynqmp.c:150:24: warning: array subscript 2562 is above
>> array bounds of 'u32[64]' {aka 'unsigned int[64]'} [-Warray-bounds]
>>> 150 | if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
>>> | ~~~~~~~~~~~~~~~~~~^~~~~~~~
>>> drivers/firmware/xilinx/zynqmp.c:28:12: note: while referencing
>> 'zynqmp_pm_features'
>>> 28 | static u32 zynqmp_pm_features[PM_API_MAX];
>>> | ^~~~~~~~~~~~~~~~~~
>>
>> Which CONFIG option/tool is reporting this issue?
>>
>>>
>>> Replace the resulting undefined behavior with an error return.
>>> This may break some things that happen to work at the moment
>>> but seems better than randomly overwriting kernel data.
>>>
>>> I assume we need additional fixes for the two functions that now
>>> return an error.
>>>
>>> Fixes: 76582671eb5d ("firmware: xilinx: Add Zynqmp firmware driver")
>>> Fixes: e178df31cf41 ("firmware: xilinx: Implement ZynqMP power management
>> APIs")
>>> Signed-off-by: Arnd Bergmann <[email protected]>
>>> ---
>>> drivers/firmware/xilinx/zynqmp.c | 3 +++
>>> 1 file changed, 3 insertions(+)
>>>
>>> diff --git a/drivers/firmware/xilinx/zynqmp.c
>> b/drivers/firmware/xilinx/zynqmp.c
>>> index 8d1ff2454e2e..efb8a66efc68 100644
>>> --- a/drivers/firmware/xilinx/zynqmp.c
>>> +++ b/drivers/firmware/xilinx/zynqmp.c
>>> @@ -147,6 +147,9 @@ static int zynqmp_pm_feature(u32 api_id)
>>> return 0;
>>>
>>> /* Return value if feature is already checked */
>>> + if (api_id > ARRAY_SIZE(zynqmp_pm_features))
>>> + return PM_FEATURE_INVALID;
>>> +
>>> if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
>>> return zynqmp_pm_features[api_id];
>>>
>>>
>>
>> Definitely good catch but not quite sure what should be correct reaction.
>> Rajan: Can you please take a look at it with priority?
> [Rajan] Change looks fine to me.

as is mentioned above that two functions now returns and error
PM_FEATURE_INVALID. Which means that zynqmp_pm_set_suspend_mode() and
zynqmp_pm_get_trustzone_version() fail all the time which doesn't look
correct.

M

2020-10-28 07:34:08

by Rajan Vaja

[permalink] [raw]
Subject: RE: [PATCH] firmware: xilinx: fix out-of-bounds access

Hi Michal,


> -----Original Message-----
> From: Michal Simek <[email protected]>
> Sent: 27 October 2020 05:27
> To: Rajan Vaja <[email protected]>; Arnd Bergmann <[email protected]>
> Cc: Arnd Bergmann <[email protected]>; Greg Kroah-Hartman
> <[email protected]>; Tejas Patel <[email protected]>; linux-arm-
> [email protected]; [email protected]; git <[email protected]>
> Subject: Re: [PATCH] firmware: xilinx: fix out-of-bounds access
>
>
>
> On 27. 10. 20 13:23, Rajan Vaja wrote:
> > Hi Michal,
> >
> >> -----Original Message-----
> >> From: Michal Simek <[email protected]>
> >> Sent: 27 October 2020 02:53
> >> To: Arnd Bergmann <[email protected]>; Michal Simek <[email protected]>;
> >> Rajan Vaja <[email protected]>
> >> Cc: Arnd Bergmann <[email protected]>; Rajan Vaja <[email protected]>;
> Greg
> >> Kroah-Hartman <[email protected]>; Tejas Patel
> >> <[email protected]>; [email protected]; linux-
> >> [email protected]; git <[email protected]>
> >> Subject: Re: [PATCH] firmware: xilinx: fix out-of-bounds access
> >>
> >>
> >>
> >> On 26. 10. 20 16:54, Arnd Bergmann wrote:
> >>> From: Arnd Bergmann <[email protected]>
> >>>
> >>> The zynqmp_pm_set_suspend_mode() and
> >> zynqmp_pm_get_trustzone_version()
> >>> functions pass values as api_id into zynqmp_pm_invoke_fn
> >>> that are beyond PM_API_MAX, resulting in an out-of-bounds access:
> >>>
> >>> drivers/firmware/xilinx/zynqmp.c: In function
> >> 'zynqmp_pm_set_suspend_mode':
> >>> drivers/firmware/xilinx/zynqmp.c:150:24: warning: array subscript 2562 is
> above
> >> array bounds of 'u32[64]' {aka 'unsigned int[64]'} [-Warray-bounds]
> >>> 150 | if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
> >>> | ~~~~~~~~~~~~~~~~~~^~~~~~~~
> >>> drivers/firmware/xilinx/zynqmp.c:28:12: note: while referencing
> >> 'zynqmp_pm_features'
> >>> 28 | static u32 zynqmp_pm_features[PM_API_MAX];
> >>> | ^~~~~~~~~~~~~~~~~~
> >>
> >> Which CONFIG option/tool is reporting this issue?
> >>
> >>>
> >>> Replace the resulting undefined behavior with an error return.
> >>> This may break some things that happen to work at the moment
> >>> but seems better than randomly overwriting kernel data.
> >>>
> >>> I assume we need additional fixes for the two functions that now
> >>> return an error.
> >>>
> >>> Fixes: 76582671eb5d ("firmware: xilinx: Add Zynqmp firmware driver")
> >>> Fixes: e178df31cf41 ("firmware: xilinx: Implement ZynqMP power
> management
> >> APIs")
> >>> Signed-off-by: Arnd Bergmann <[email protected]>
> >>> ---
> >>> drivers/firmware/xilinx/zynqmp.c | 3 +++
> >>> 1 file changed, 3 insertions(+)
> >>>
> >>> diff --git a/drivers/firmware/xilinx/zynqmp.c
> >> b/drivers/firmware/xilinx/zynqmp.c
> >>> index 8d1ff2454e2e..efb8a66efc68 100644
> >>> --- a/drivers/firmware/xilinx/zynqmp.c
> >>> +++ b/drivers/firmware/xilinx/zynqmp.c
> >>> @@ -147,6 +147,9 @@ static int zynqmp_pm_feature(u32 api_id)
> >>> return 0;
> >>>
> >>> /* Return value if feature is already checked */
> >>> + if (api_id > ARRAY_SIZE(zynqmp_pm_features))
> >>> + return PM_FEATURE_INVALID;
> >>> +
> >>> if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
> >>> return zynqmp_pm_features[api_id];
> >>>
> >>>
> >>
> >> Definitely good catch but not quite sure what should be correct reaction.
> >> Rajan: Can you please take a look at it with priority?
> > [Rajan] Change looks fine to me.
>
> as is mentioned above that two functions now returns and error
> PM_FEATURE_INVALID. Which means that zynqmp_pm_set_suspend_mode()
> and
> zynqmp_pm_get_trustzone_version() fail all the time which doesn't look
> correct.
[Rajan] Right Michal, I completely missed API which are not in pmufw , API IDs from ATF are different and it doesn't fit in PM_API_MAX range, so I think instead of just single array with PM_API_MAX size, implementation can be updated having, hash table kind of implementation and not directly in array index which is same as API ID.

Thanks,
Rajan
>
> M

2020-10-28 07:49:00

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH] firmware: xilinx: fix out-of-bounds access

On Tue, Oct 27, 2020 at 10:53 AM Michal Simek <[email protected]> wrote:
> On 26. 10. 20 16:54, Arnd Bergmann wrote:
> > From: Arnd Bergmann <[email protected]>
> >
> > The zynqmp_pm_set_suspend_mode() and zynqmp_pm_get_trustzone_version()
> > functions pass values as api_id into zynqmp_pm_invoke_fn
> > that are beyond PM_API_MAX, resulting in an out-of-bounds access:
> >
> > drivers/firmware/xilinx/zynqmp.c: In function 'zynqmp_pm_set_suspend_mode':
> > drivers/firmware/xilinx/zynqmp.c:150:24: warning: array subscript 2562 is above array bounds of 'u32[64]' {aka 'unsigned int[64]'} [-Warray-bounds]
> > 150 | if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
> > | ~~~~~~~~~~~~~~~~~~^~~~~~~~
> > drivers/firmware/xilinx/zynqmp.c:28:12: note: while referencing 'zynqmp_pm_features'
> > 28 | static u32 zynqmp_pm_features[PM_API_MAX];
> > | ^~~~~~~~~~~~~~~~~~
>
> Which CONFIG option/tool is reporting this issue?

This is with gcc-10. Commit 44720996e2d7 ("gcc-10: disable
'array-bounds' warning for
now") turned off this warning globally, but most of the reported warnings got
fixed in the meantime. I'm trying to take care of the rest so we can enabled it
again.

You should be able to reproduce the problem by removing the cc-disable-warning
line from the top-level Makefile.

Arnd