From: sashiko-bot@kernel.org
To: "Fenglin Wu" <fenglin.wu@oss.qualcomm.com>
Cc: lee@kernel.org, linux-leds@vger.kernel.org
Subject: Re: [PATCH v3] leds: rgb: leds-qcom-lpg: Fix LED color balancing in HW pattern mode
Date: Mon, 29 Jun 2026 10:01:46 +0000 [thread overview]
Message-ID: <20260629100147.097A11F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260629-lpg-rgb-color-balance-fix-v3-1-17796a06d799@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] Failing to inhibit cleanup of the __free() 'pattern' variable in lpg_prepare_pattern() causes it to be freed on success, leading to Use-After-Free and Double-Free in callers.
- [Low] Mixing goto-based error handling with scope-based cleanup (__free and guard) violates subsystem guidelines and causes a compilation error.
--
commit 6d61dc847ec65d99f5fb5a8faf11368f527f4b5c
Author: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
leds: rgb: leds-qcom-lpg: Fix LED color balancing in HW pattern mode
This patch updates the LED pattern programming to scale pattern data
according to sub-LED intensities. This ensures proper white balancing
when using hardware patterns.
> diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
> --- a/drivers/leds/rgb/leds-qcom-lpg.c
> +++ b/drivers/leds/rgb/leds-qcom-lpg.c
[ ... ]
> @@ -959,23 +977,15 @@ static int lpg_blink_mc_set(struct led_classdev *cdev,
> +static int lpg_prepare_pattern(struct lpg *lpg, struct led_pattern *led_pattern,
> + u32 len, int repeat, struct lpg_pattern *prep)
> {
[ ... ]
> - pattern = kzalloc_objs(*pattern, len / 2);
> + struct led_pattern *pattern __free(kfree) = kzalloc_objs(*pattern, len / 2);
> +
> if (!pattern)
> return -ENOMEM;
[ ... ]
> + prep->data = pattern;
> + prep->len = actual_len;
> + prep->delta_t = delta_t;
> + prep->ping_pong = ping_pong;
>
> - mutex_lock(&lpg->lock);
> + return 0;
> +}
[Severity: Critical]
Since pattern is declared with __free(kfree), does returning 0 without
inhibiting cleanup cause pattern to be freed immediately upon function
exit? Could this be resolved by using no_free_ptr(pattern) when assigning
it to prep->data?
> +static int lpg_pattern_set(struct lpg_led *led, struct led_pattern *led_pattern,
> + u32 len, int repeat)
> +{
[ ... ]
> + guard(mutex)(&lpg->lock);
>
> if (lpg->lut_base)
> - ret = lpg_lut_store(lpg, pattern, actual_len, &lo_idx, &hi_idx);
> + ret = lpg_lut_store(lpg, pattern.data, pattern.len, &lo_idx, &hi_idx);
> else
> - ret = lpg_lut_store_sdam(lpg, pattern, actual_len, &lo_idx, &hi_idx);
> + ret = lpg_lut_store_sdam(lpg, pattern.data, pattern.len, &lo_idx, &hi_idx);
>
> if (ret < 0)
> - goto out_unlock;
> + goto free_pattern;
[Severity: Low]
Does mixing goto-based cleanup labels with scope-based cleanup like
guard(mutex) violate the kernel's cleanup guidelines? The guidelines
recommend either converting all resources to scope-based cleanup or not
using it at all in the same function.
[ ... ]
> -out_unlock:
> - mutex_unlock(&lpg->lock);
> -out_free_pattern:
> - kfree(pattern);
> -
> +free_pattern:
> + kfree(pattern.data);
> return ret;
> }
[ ... ]
> static int lpg_pattern_mc_set(struct led_classdev *cdev,
> - struct led_pattern *pattern, u32 len,
> + struct led_pattern *led_pattern, u32 len,
> int repeat)
> {
[ ... ]
> + /* Allocate buffer for the per-channel scaled pattern copy */
> + struct led_pattern *scaled __free(kfree) =
> + kmalloc_array(pattern.len, sizeof(*scaled), GFP_KERNEL);
> + if (!scaled) {
> + ret = -ENOMEM;
> + goto free_pattern;
> + }
[Severity: Low]
Does jumping to free_pattern on this error path skip the declaration of
guard(mutex)(&lpg->lock) further down in the function? In C, jumping
forward over a variable initialized with a cleanup attribute results in a
compilation error.
[ ... ]
> + guard(mutex)(&lpg->lock);
> +
> + for (i = 0; i < led->num_channels; i++) {
> + chan = led->channels[i];
> + scale = mc->subled_info[i].brightness;
> +
> + for (j = 0; j < pattern.len; j++) {
> + scaled[j].brightness = DIV_ROUND_CLOSEST(
> + (u32)pattern.data[j].brightness * scale, LED_FULL);
[Severity: Critical]
If pattern.data was already freed at the end of lpg_prepare_pattern(),
can this loop dereference freed memory?
> + scaled[j].delta_t = pattern.data[j].delta_t;
> + }
[ ... ]
> +free_pattern:
> + kfree(pattern.data);
[Severity: Critical]
Would this unconditional kfree() trigger a double-free, since pattern.data
was already freed upon exiting lpg_prepare_pattern()?
> if (ret < 0)
> return ret;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260629-lpg-rgb-color-balance-fix-v3-1-17796a06d799@oss.qualcomm.com?part=1
next prev parent reply other threads:[~2026-06-29 10:01 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-29 9:51 [PATCH v3] leds: rgb: leds-qcom-lpg: Fix LED color balancing in HW pattern mode Fenglin Wu
2026-06-29 10:01 ` sashiko-bot [this message]
2026-06-29 15:05 ` kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260629100147.097A11F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=fenglin.wu@oss.qualcomm.com \
--cc=lee@kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox