diff mbox series

memory: gpmc: fix out of bounds read and dereference on gpmc_cs[]

Message ID 20210223193821.17232-1-colin.king@canonical.com (mailing list archive)
State New
Headers show
Series memory: gpmc: fix out of bounds read and dereference on gpmc_cs[] | expand

Commit Message

Colin Ian King Feb. 23, 2021, 7:38 p.m. UTC
From: Colin Ian King <colin.king@canonical.com>

Currently the array gpmc_cs is indexed by cs before it cs is range checked
and the pointer read from this out-of-index read is dereferenced. Fix this
by performing the range check on cs before the read and the following
pointer dereference.

Addresses-Coverity: ("Negative array index read")
Fixes: 186401937927 ("memory: gpmc: Move omap gpmc code to live under drivers")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 drivers/memory/omap-gpmc.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Comments

Krzysztof Kozlowski Feb. 23, 2021, 7:52 p.m. UTC | #1
On Tue, Feb 23, 2021 at 07:38:21PM +0000, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
> 
> Currently the array gpmc_cs is indexed by cs before it cs is range checked
> and the pointer read from this out-of-index read is dereferenced. Fix this
> by performing the range check on cs before the read and the following
> pointer dereference.
> 
> Addresses-Coverity: ("Negative array index read")
> Fixes: 186401937927 ("memory: gpmc: Move omap gpmc code to live under drivers")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
>  drivers/memory/omap-gpmc.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)

Thanks, looks good. I'll take it after merge window.

Best regards,
Krzysztof
Dan Carpenter Feb. 24, 2021, 7:55 a.m. UTC | #2
On Tue, Feb 23, 2021 at 07:38:21PM +0000, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
> 
> Currently the array gpmc_cs is indexed by cs before it cs is range checked
> and the pointer read from this out-of-index read is dereferenced. Fix this
> by performing the range check on cs before the read and the following
> pointer dereference.
> 
> Addresses-Coverity: ("Negative array index read")
> Fixes: 186401937927 ("memory: gpmc: Move omap gpmc code to live under drivers")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
>  drivers/memory/omap-gpmc.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
> index cfa730cfd145..f80c2ea39ca4 100644
> --- a/drivers/memory/omap-gpmc.c
> +++ b/drivers/memory/omap-gpmc.c
> @@ -1009,8 +1009,8 @@ EXPORT_SYMBOL(gpmc_cs_request);
>  
>  void gpmc_cs_free(int cs)
>  {
> -	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
> -	struct resource *res = &gpmc->mem;

There is no actual dereferencing going on here, it just taking the
addresses.  But the patch is also harmless and improves readability.

regards,
dan carpenter
Krzysztof Kozlowski Feb. 24, 2021, 8:11 a.m. UTC | #3
On Wed, Feb 24, 2021 at 10:55:52AM +0300, Dan Carpenter wrote:
> On Tue, Feb 23, 2021 at 07:38:21PM +0000, Colin King wrote:
> > From: Colin Ian King <colin.king@canonical.com>
> > 
> > Currently the array gpmc_cs is indexed by cs before it cs is range checked
> > and the pointer read from this out-of-index read is dereferenced. Fix this
> > by performing the range check on cs before the read and the following
> > pointer dereference.
> > 
> > Addresses-Coverity: ("Negative array index read")
> > Fixes: 186401937927 ("memory: gpmc: Move omap gpmc code to live under drivers")
> > Signed-off-by: Colin Ian King <colin.king@canonical.com>
> > ---
> >  drivers/memory/omap-gpmc.c | 7 +++++--
> >  1 file changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
> > index cfa730cfd145..f80c2ea39ca4 100644
> > --- a/drivers/memory/omap-gpmc.c
> > +++ b/drivers/memory/omap-gpmc.c
> > @@ -1009,8 +1009,8 @@ EXPORT_SYMBOL(gpmc_cs_request);
> >  
> >  void gpmc_cs_free(int cs)
> >  {
> > -	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
> > -	struct resource *res = &gpmc->mem;
> 
> There is no actual dereferencing going on here, it just taking the
> addresses.  But the patch is also harmless and improves readability.

Hm, in the second line indeed the compiler will just calculate the
offset of "mem" field against the "gpmc_cs+cs" and return it's probable
address.

To me still the code is a little bit non-obvious or obfuscated - first
you play with the array[index] and then you check the validity of index.

Best regards,
Krzysztof
Colin Ian King Feb. 24, 2021, 8:46 a.m. UTC | #4
On 24/02/2021 07:55, Dan Carpenter wrote:
> On Tue, Feb 23, 2021 at 07:38:21PM +0000, Colin King wrote:
>> From: Colin Ian King <colin.king@canonical.com>
>>
>> Currently the array gpmc_cs is indexed by cs before it cs is range checked
>> and the pointer read from this out-of-index read is dereferenced. Fix this
>> by performing the range check on cs before the read and the following
>> pointer dereference.
>>
>> Addresses-Coverity: ("Negative array index read")
>> Fixes: 186401937927 ("memory: gpmc: Move omap gpmc code to live under drivers")
>> Signed-off-by: Colin Ian King <colin.king@canonical.com>
>> ---
>>  drivers/memory/omap-gpmc.c | 7 +++++--
>>  1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
>> index cfa730cfd145..f80c2ea39ca4 100644
>> --- a/drivers/memory/omap-gpmc.c
>> +++ b/drivers/memory/omap-gpmc.c
>> @@ -1009,8 +1009,8 @@ EXPORT_SYMBOL(gpmc_cs_request);
>>  
>>  void gpmc_cs_free(int cs)
>>  {
>> -	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
>> -	struct resource *res = &gpmc->mem;
> > There is no actual dereferencing going on here, it just taking the
> addresses.  But the patch is also harmless and improves readability.

Plus compilers are getting smarter with static analysis so some day in
the future they will warn about this.


> 
> regards,
> dan carpenter
>
Tony Lindgren Feb. 25, 2021, 12:37 p.m. UTC | #5
* Krzysztof Kozlowski <krzk@kernel.org> [210224 08:11]:
> On Wed, Feb 24, 2021 at 10:55:52AM +0300, Dan Carpenter wrote:
> > On Tue, Feb 23, 2021 at 07:38:21PM +0000, Colin King wrote:
> > > From: Colin Ian King <colin.king@canonical.com>
> > > 
> > > Currently the array gpmc_cs is indexed by cs before it cs is range checked
> > > and the pointer read from this out-of-index read is dereferenced. Fix this
> > > by performing the range check on cs before the read and the following
> > > pointer dereference.
> > > 
> > > Addresses-Coverity: ("Negative array index read")
> > > Fixes: 186401937927 ("memory: gpmc: Move omap gpmc code to live under drivers")
> > > Signed-off-by: Colin Ian King <colin.king@canonical.com>
> > > ---
> > >  drivers/memory/omap-gpmc.c | 7 +++++--
> > >  1 file changed, 5 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
> > > index cfa730cfd145..f80c2ea39ca4 100644
> > > --- a/drivers/memory/omap-gpmc.c
> > > +++ b/drivers/memory/omap-gpmc.c
> > > @@ -1009,8 +1009,8 @@ EXPORT_SYMBOL(gpmc_cs_request);
> > >  
> > >  void gpmc_cs_free(int cs)
> > >  {
> > > -	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
> > > -	struct resource *res = &gpmc->mem;
> > 
> > There is no actual dereferencing going on here, it just taking the
> > addresses.  But the patch is also harmless and improves readability.
> 
> Hm, in the second line indeed the compiler will just calculate the
> offset of "mem" field against the "gpmc_cs+cs" and return it's probable
> address.
> 
> To me still the code is a little bit non-obvious or obfuscated - first
> you play with the array[index] and then you check the validity of index.

To me it seems the fixes tag is not ideal.. Seems this issue was there
earlier too before moving the code. In any case:

Reviewed-by: Tony Lindgren <tony@atomide.com>
Krzysztof Kozlowski March 2, 2021, 8:44 a.m. UTC | #6
On Tue, Feb 23, 2021 at 07:38:21PM +0000, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
> 
> Currently the array gpmc_cs is indexed by cs before it cs is range checked
> and the pointer read from this out-of-index read is dereferenced. Fix this
> by performing the range check on cs before the read and the following
> pointer dereference.
> 
> Addresses-Coverity: ("Negative array index read")
> Fixes: 186401937927 ("memory: gpmc: Move omap gpmc code to live under drivers")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
>  drivers/memory/omap-gpmc.c | 7 +++++--

Thanks, applied with Tony's ack and changed Fixes to 9ed7a776eb50 ("ARM:
OMAP2+: Fix support for multiple devices on a GPMC chip select"). 

Best regards,
Krzysztof
Colin Ian King March 2, 2021, 8:54 a.m. UTC | #7
On 02/03/2021 08:44, Krzysztof Kozlowski wrote:
> On Tue, Feb 23, 2021 at 07:38:21PM +0000, Colin King wrote:
>> From: Colin Ian King <colin.king@canonical.com>
>>
>> Currently the array gpmc_cs is indexed by cs before it cs is range checked
>> and the pointer read from this out-of-index read is dereferenced. Fix this
>> by performing the range check on cs before the read and the following
>> pointer dereference.
>>
>> Addresses-Coverity: ("Negative array index read")
>> Fixes: 186401937927 ("memory: gpmc: Move omap gpmc code to live under drivers")
>> Signed-off-by: Colin Ian King <colin.king@canonical.com>
>> ---
>>  drivers/memory/omap-gpmc.c | 7 +++++--
> 
> Thanks, applied with Tony's ack and changed Fixes to 9ed7a776eb50 ("ARM:
> OMAP2+: Fix support for multiple devices on a GPMC chip select"). 


Thanks for correcting the Fixes line

> 
> Best regards,
> Krzysztof
>
diff mbox series

Patch

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index cfa730cfd145..f80c2ea39ca4 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -1009,8 +1009,8 @@  EXPORT_SYMBOL(gpmc_cs_request);
 
 void gpmc_cs_free(int cs)
 {
-	struct gpmc_cs_data *gpmc = &gpmc_cs[cs];
-	struct resource *res = &gpmc->mem;
+	struct gpmc_cs_data *gpmc;
+	struct resource *res;
 
 	spin_lock(&gpmc_mem_lock);
 	if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
@@ -1018,6 +1018,9 @@  void gpmc_cs_free(int cs)
 		spin_unlock(&gpmc_mem_lock);
 		return;
 	}
+	gpmc = &gpmc_cs[cs];
+	res = &gpmc->mem;
+
 	gpmc_cs_disable_mem(cs);
 	if (res->flags)
 		release_resource(res);