On Wed, Apr 3, 2024 at 3:15 PM Kent Gibson <warthog618@xxxxxxxxx> wrote: > > When adding sanitization of the label, the path through > edge_detector_setup() that leads to debounce_setup() was overlooked. > A request taking this path does not allocate a new label and the > request label is freed twice when the request is released, resulting > in memory corruption. > > Add label sanitization to debounce_setup(). > > Cc: stable@xxxxxxxxxxxxxxx > Fixes: b34490879baa ("gpio: cdev: sanitize the label before requesting the interrupt") > Signed-off-by: Kent Gibson <warthog618@xxxxxxxxx> > --- > drivers/gpio/gpiolib-cdev.c | 31 +++++++++++++++++++------------ > 1 file changed, 19 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c > index fa9635610251..f4c2da2041e5 100644 > --- a/drivers/gpio/gpiolib-cdev.c > +++ b/drivers/gpio/gpiolib-cdev.c > @@ -728,6 +728,16 @@ static u32 line_event_id(int level) > GPIO_V2_LINE_EVENT_FALLING_EDGE; > } > > +static inline char *make_irq_label(const char *orig) > +{ > + return kstrdup_and_replace(orig, '/', ':', GFP_KERNEL); > +} > + > +static inline void free_irq_label(const char *label) > +{ > + kfree(label); > +} > + > #ifdef CONFIG_HTE > > static enum hte_return process_hw_ts_thread(void *p) > @@ -1015,6 +1025,7 @@ static int debounce_setup(struct line *line, unsigned int debounce_period_us) > { > unsigned long irqflags; > int ret, level, irq; > + char *label; > > /* try hardware */ > ret = gpiod_set_debounce(line->desc, debounce_period_us); > @@ -1037,11 +1048,17 @@ static int debounce_setup(struct line *line, unsigned int debounce_period_us) > if (irq < 0) > return -ENXIO; > > + label = make_irq_label(line->req->label); Now that I look at the actual patch, I don't really like it. We introduce a bug just to fix it a commit later. Such things have been frowned upon in the past. Let me shuffle the code a bit, I'll try to make it a bit more correct. Bart > + if (!label) > + return -ENOMEM; > + > irqflags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING; > ret = request_irq(irq, debounce_irq_handler, irqflags, > - line->req->label, line); > - if (ret) > + label, line); > + if (ret) { > + free_irq_label(label); > return ret; > + } > line->irq = irq; > } else { > ret = hte_edge_setup(line, GPIO_V2_LINE_FLAG_EDGE_BOTH); > @@ -1083,16 +1100,6 @@ static u32 gpio_v2_line_config_debounce_period(struct gpio_v2_line_config *lc, > return 0; > } > > -static inline char *make_irq_label(const char *orig) > -{ > - return kstrdup_and_replace(orig, '/', ':', GFP_KERNEL); > -} > - > -static inline void free_irq_label(const char *label) > -{ > - kfree(label); > -} > - > static void edge_detector_stop(struct line *line) > { > if (line->irq) { > -- > 2.39.2 >