lkml.org 
[lkml]   [2021]   [Sep]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 012/260] pinctrl: stmfx: Fix hazardous u8[] to unsigned long cast
    Date
    From: Marc Zyngier <maz@kernel.org>

    commit 1b73e588f47397dee6e4bdfd953e0306c60b5fe5 upstream.

    Casting a small array of u8 to an unsigned long is *never* OK:

    - it does funny thing when the array size is less than that of a long,
    as it accesses random places in the stack
    - it makes everything even more fun with a BE kernel

    Fix this by building the unsigned long used as a bitmap byte by byte,
    in a way that works across endianess and has no undefined behaviours.

    An extra BUILD_BUG_ON() catches the unlikely case where the array
    would be larger than a single unsigned long.

    Fixes: 1490d9f841b1 ("pinctrl: Add STMFX GPIO expander Pinctrl/GPIO driver")
    Signed-off-by: Marc Zyngier <maz@kernel.org>
    Cc: stable@vger.kernel.org
    Cc: Amelie Delaunay <amelie.delaunay@foss.st.com>
    Cc: Linus Walleij <linus.walleij@linaro.org>
    Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
    Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
    Link: https://lore.kernel.org/r/20210725180830.250218-1-maz@kernel.org
    Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/pinctrl/pinctrl-stmfx.c | 6 ++++--
    1 file changed, 4 insertions(+), 2 deletions(-)

    --- a/drivers/pinctrl/pinctrl-stmfx.c
    +++ b/drivers/pinctrl/pinctrl-stmfx.c
    @@ -540,7 +540,7 @@ static irqreturn_t stmfx_pinctrl_irq_thr
    u8 pending[NR_GPIO_REGS];
    u8 src[NR_GPIO_REGS] = {0, 0, 0};
    unsigned long n, status;
    - int ret;
    + int i, ret;

    ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_IRQ_GPI_PENDING,
    &pending, NR_GPIO_REGS);
    @@ -550,7 +550,9 @@ static irqreturn_t stmfx_pinctrl_irq_thr
    regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC,
    src, NR_GPIO_REGS);

    - status = *(unsigned long *)pending;
    + BUILD_BUG_ON(NR_GPIO_REGS > sizeof(status));
    + for (i = 0, status = 0; i < NR_GPIO_REGS; i++)
    + status |= (unsigned long)pending[i] << (i * 8);
    for_each_set_bit(n, &status, gc->ngpio) {
    handle_nested_irq(irq_find_mapping(gc->irq.domain, n));
    stmfx_pinctrl_irq_toggle_trigger(pctl, n);

    \
     
     \ /
      Last update: 2021-09-20 20:07    [W:4.092 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site