This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 6bec3b6f5bf arch/arm64/imx9: reject PWM channels outside the timer
6bec3b6f5bf is described below
commit 6bec3b6f5bf025764d7053ab6927172b917bbcb1
Author: Royyan Zahir <[email protected]>
AuthorDate: Wed Sep 30 12:18:25 2026 +0400
arch/arm64/imx9: reject PWM channels outside the timer
A negative channel passed both checks, and TPM took one past the end,
so a caller could write FlexIO and TPM registers it does not own. TPM
also dropped the error and reported success.
Signed-off-by: Royyan Zahir <[email protected]>
---
arch/arm64/src/imx9/imx9_flexio_pwm.c | 3 ++-
arch/arm64/src/imx9/imx9_tpm_pwm.c | 25 ++++++++++++-------------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/src/imx9/imx9_flexio_pwm.c
b/arch/arm64/src/imx9/imx9_flexio_pwm.c
index c1bb241335c..be123a464d1 100644
--- a/arch/arm64/src/imx9/imx9_flexio_pwm.c
+++ b/arch/arm64/src/imx9/imx9_flexio_pwm.c
@@ -393,6 +393,7 @@ static int pwm_select_func_clock(struct imx9_pwmtimer_s
*priv, int freq)
static int pwm_update_frequency(struct imx9_pwmtimer_s *priv, int freq)
{
int ret = pwm_select_func_clock(priv, freq);
+
if (ret < 0)
{
return ret;
@@ -450,7 +451,7 @@ static int pwm_update_duty(struct imx9_pwmtimer_s *priv,
int pwm_ch,
int timer = pwm_ch - 1; /* map pwm ch 1 to timer 0 etc.. */
uint32_t regval;
- if (pwm_ch == 0 || pwm_ch > priv->nchannels)
+ if (pwm_ch < 1 || pwm_ch > priv->nchannels)
{
pwmerr("ERROR: PWM%d has no such channel: %u\n", priv->id, pwm_ch);
return -EINVAL;
diff --git a/arch/arm64/src/imx9/imx9_tpm_pwm.c
b/arch/arm64/src/imx9/imx9_tpm_pwm.c
index 9e73f596c43..bfc7884d92d 100644
--- a/arch/arm64/src/imx9/imx9_tpm_pwm.c
+++ b/arch/arm64/src/imx9/imx9_tpm_pwm.c
@@ -439,7 +439,7 @@ static int pwm_update_duty(struct imx9_pwmtimer_s *priv,
int pwm_ch,
uint32_t edge = (duty * priv->period + 0x8000) >> 16;
int timer = pwm_ch - 1;
- if (pwm_ch == 0 || timer > priv->n_channels)
+ if (pwm_ch < 1 || pwm_ch > priv->n_channels)
{
pwmerr("ERROR: PWM%d has no such channel: %d\n", priv->id, timer);
return -EINVAL;
@@ -520,7 +520,7 @@ static int pwm_start(struct pwm_lowerhalf_s *dev,
const struct pwm_info_s *info)
{
struct imx9_pwmtimer_s *priv = (struct imx9_pwmtimer_s *)dev;
- int ret = OK;
+ int ret;
int i;
if (priv == NULL || info == NULL || info->frequency == 0)
@@ -530,20 +530,19 @@ static int pwm_start(struct pwm_lowerhalf_s *dev,
/* Set the frequency if not changed */
- if (pwm_update_frequency(priv, info->frequency) == OK)
- {
- /* Handle channel specific setup */
+ ret = pwm_update_frequency(priv, info->frequency);
- for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
- {
- if (ret != OK || info->channels[i].channel == -1)
- {
- break;
- }
+ /* Handle channel specific setup */
- pwm_update_duty(priv, info->channels[i].channel,
- info->channels[i].duty);
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ if (ret != OK || info->channels[i].channel == -1)
+ {
+ break;
}
+
+ ret = pwm_update_duty(priv, info->channels[i].channel,
+ info->channels[i].duty);
}
return ret;