Message ID | 20240404093328.21604-2-brgl@bgdev.pl |
---|---|
State | New |
Headers | show |
Series | gpio: cdev: label sanitization fixes | expand |
On Thu, Apr 4, 2024 at 11:33 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote: > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > We need to take into account that a line's consumer label may be NULL > and not try to kstrdup() it in that case but rather pass the NULL > pointer up the stack to the interrupt request function. > > To that end: let make_irq_label() return NULL as a valid return value > and use ERR_PTR() instead to signal an allocation failure to callers. > > Cc: stable@vger.kernel.org > Fixes: b34490879baa ("gpio: cdev: sanitize the label before requesting the interrupt") > Reported-by: Linux Kernel Functional Testing <lkft@linaro.org> > Closes: https://lore.kernel.org/lkml/20240402093534.212283-1-naresh.kamboju@linaro.org/ > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > --- Tested-by: Anders Roxell <anders.roxell@linaro.org>
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index fa9635610251..1426cc1c4a28 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1085,7 +1085,16 @@ static u32 gpio_v2_line_config_debounce_period(struct gpio_v2_line_config *lc, static inline char *make_irq_label(const char *orig) { - return kstrdup_and_replace(orig, '/', ':', GFP_KERNEL); + char *new; + + if (!orig) + return NULL; + + new = kstrdup_and_replace(orig, '/', ':', GFP_KERNEL); + if (!new) + return ERR_PTR(-ENOMEM); + + return new; } static inline void free_irq_label(const char *label) @@ -1158,8 +1167,8 @@ static int edge_detector_setup(struct line *line, irqflags |= IRQF_ONESHOT; label = make_irq_label(line->req->label); - if (!label) - return -ENOMEM; + if (IS_ERR(label)) + return PTR_ERR(label); /* Request a thread to read the events */ ret = request_threaded_irq(irq, edge_irq_handler, edge_irq_thread, @@ -2217,8 +2226,8 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) goto out_free_le; label = make_irq_label(le->label); - if (!label) { - ret = -ENOMEM; + if (IS_ERR(label)) { + ret = PTR_ERR(label); goto out_free_le; }