qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/1] hw: aspeed_gpio: Fix GPIO array indexing


From: Peter Delevoryas
Subject: Re: [PATCH 1/1] hw: aspeed_gpio: Fix GPIO array indexing
Date: Fri, 8 Oct 2021 03:19:25 +0000


> On Oct 4, 2021, at 4:43 AM, Cédric Le Goater <clg@kaod.org> wrote:
> 
> On 10/4/21 11:07, Cédric Le Goater wrote:
>> On 9/28/21 05:43, pdel@fb.com wrote:
>>> From: Peter Delevoryas <pdel@fb.com>
>>> 
>>> The gpio array is declared as a dense array:
>>> 
>>>    qemu_irq gpios[ASPEED_GPIO_NR_PINS];
>>> 
>>> (AST2500 has 228, AST2400 has 216, AST2600 has 208)
>>> 
>>> However, this array is used like a matrix of GPIO sets
>>> (e.g. gpio[NR_SETS][NR_PINS_PER_SET] = gpio[8][32])
>>> 
>>>    size_t offset = set * GPIOS_PER_SET + gpio;
>>>    qemu_set_irq(s->gpios[offset], !!(new & mask));
>>> 
>>> This can result in an out-of-bounds access to "s->gpios" because the
>>> gpio sets do _not_ have the same length. Some of the groups (e.g.
>>> GPIOAB) only have 4 pins. 228 != 8 * 32 == 256.
>>> 
>>> To fix this, I converted the gpio array from dense to sparse, to match
>>> both the hardware layout and this existing indexing code.
>>> 
>>> Fixes: 4b7f956862dc2db4c5c ("hw/gpio: Add basic Aspeed GPIO model for 
>>> AST2400 and AST2500")
>>> Signed-off-by: Peter Delevoryas <pdel@fb.com>
>> This patch is raising an error in qtest-arm/qom-test when compiled
>> with clang :
>> Running test qtest-arm/qom-test
>> Unexpected error in object_property_try_add() at ../qom/object.c:1224:
>> qemu-system-arm: attempt to add duplicate property 'gpio0' to object (type 
>> 'aspeed.gpio-ast2600-1_8v')
>> Broken pipe
>> ERROR qtest-arm/qom-test - too few tests run (expected 78, got 0)
>> make: *** [Makefile.mtest:24: run-test-1] Error 1
> 
> The GPIOSetProperties arrary is smaller for the ast2600_1_8v model :
> 
>  static GPIOSetProperties ast2600_1_8v_set_props[] = {
>      [0] = {0xffffffff,  0xffffffff,  {"18A", "18B", "18C", "18D"} },
>      [1] = {0x0000000f,  0x0000000f,  {"18E"} },
>  };
> 
> and in aspeed_gpio_init() :
> 
>    for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
> 
> we loop beyond.
> 
> To configure compilation with clang, use the configure option :
> 
>  --cc=clang
> 
> and simply run 'make check-qtest-arm'

Thanks for pointing this out! To fix it, I think the simplest thing I could do
is just make sure all of the GPIOSetProperties arrays have the same length,
ASPEED_GPIO_MAX_NR_SETS. There is already a filtering mechanism in place in
the code that iterates over the properties to skip zeroed entries. 
Alternatively,
we could keep some variable length nr_sets value with each class, but I figured
that is more complicated and error-prone. I’m submitting the v2 version
with this fix.

Thanks,
Peter

diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index 911d21c8cf..78b0f64b03 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -759,7 +759,7 @@ static void aspeed_gpio_set_pin(Object *obj, Visitor *v, 
const char *name,
 }

 /****************** Setup functions ******************/
-static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
+static const GPIOSetProperties ast2400_set_props[] = {
     [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
     [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
     [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
@@ -769,7 +769,7 @@ static const GPIOSetProperties 
ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
     [6] = {0x0000000f,  0x0fffff0f,  {"Y", "Z", "AA", "AB"} },
 };

-static const GPIOSetProperties ast2500_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
+static const GPIOSetProperties ast2500_set_props[] = {
     [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
     [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
     [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
@@ -780,7 +780,7 @@ static const GPIOSetProperties 
ast2500_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
     [7] = {0x000000ff,  0x000000ff,  {"AC"} },
 };

-static GPIOSetProperties ast2600_3_3v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
+static GPIOSetProperties ast2600_3_3v_set_props[] = {
     [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
     [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
     [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
@@ -790,7 +790,7 @@ static GPIOSetProperties 
ast2600_3_3v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
     [6] = {0x0000ffff,  0x0000ffff,  {"Y", "Z"} },
 };

-static GPIOSetProperties ast2600_1_8v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
+static GPIOSetProperties ast2600_1_8v_set_props[] = {
     [0] = {0xffffffff,  0xffffffff,  {"18A", "18B", "18C", "18D"} },
     [1] = {0x0000000f,  0x0000000f,  {"18E"} },
 };

> 
> Thanks
> 
> C.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]