* [PATCH] ALSA: hdsp: Fix divide-by-zero in DDS offset control
@ 2026-11-04 8:30 songxiebing
2026-11-04 9:00 ` [PATCH v2] ALSA: hdsp: Validate DDS offset range and propagate errors songxiebing
2026-11-04 10:09 ` [PATCH] ALSA: hdsp: Fix divide-by-zero in DDS offset control Takashi Iwai
0 siblings, 2 replies; 3+ messages in thread
From: songxiebing @ 2026-11-04 8:30 UTC (permalink / raw)
To: tiwai, perex; +Cc: linux-sound, linux-kernel, songxiebing, stable
From: Bob Song <songxiebing@kylinos.cn>
hdsp_set_dds_offset() computes the target rate as
system_sample_rate + offset_hz without validating the result. A user
can set the DDS offset to -system_sample_rate through the control API,
making rate zero and causing div_u64() in hdsp_set_dds_value() to
divide by zero.
Reject non-positive rates before programming the DDS value.
Fixes: e4b6088c8cf1 ("[ALSA] hdsp - Add support for fine tuning of sample rate support to HDSP 9632")
Cc: <stable@vger.kernel.org>
Signed-off-by: Bob Song <songxiebing@kylinos.cn>
---
sound/pci/rme9652/hdsp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 7dce548b9f36..694816f966d2 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -2802,6 +2802,9 @@ static int hdsp_dds_offset(struct hdsp *hdsp)
static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz)
{
int rate = hdsp->system_sample_rate + offset_hz;
+
+ if (rate <= 0)
+ return -EINVAL;
hdsp_set_dds_value(hdsp, rate);
return 0;
}
--
2.25.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2] ALSA: hdsp: Validate DDS offset range and propagate errors
2026-11-04 8:30 [PATCH] ALSA: hdsp: Fix divide-by-zero in DDS offset control songxiebing
@ 2026-11-04 9:00 ` songxiebing
2026-11-04 10:09 ` [PATCH] ALSA: hdsp: Fix divide-by-zero in DDS offset control Takashi Iwai
1 sibling, 0 replies; 3+ messages in thread
From: songxiebing @ 2026-11-04 9:00 UTC (permalink / raw)
To: tiwai, perex; +Cc: linux-sound, linux-kernel, songxiebing, stable
From: Bob Song <songxiebing@kylinos.cn>
hdsp_set_dds_offset() computes the target rate as
system_sample_rate + offset_hz without validating the result. A user
can set the DDS offset to -system_sample_rate through the control API,
making rate zero and causing div_u64() in hdsp_set_dds_value() to
divide by zero. Larger offsets can also overflow the rate calculation
or push the DDS value out of range.
Validate offset_hz against the [-5000, 5000] range advertised by the
control, keep the non-positive rate check as a safety net, and
propagate the error from snd_hdsp_put_dds_offset() instead of
reporting success.
Fixes: e4b6088c8cf1 ("[ALSA] hdsp - Add support for fine tuning of sample rate support to HDSP 9632")
Cc: <stable@vger.kernel.org>
Signed-off-by: Bob Song <songxiebing@kylinos.cn>
---
sound/pci/rme9652/hdsp.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 7dce548b9f36..467121a5fb4f 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -2768,6 +2768,9 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn
return 0;
}
+#define HDSP_DDS_OFFSET_MIN -5000
+#define HDSP_DDS_OFFSET_MAX 5000
+
#define HDSP_DDS_OFFSET(xname, xindex) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
.name = xname, \
@@ -2801,7 +2804,15 @@ static int hdsp_dds_offset(struct hdsp *hdsp)
static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz)
{
- int rate = hdsp->system_sample_rate + offset_hz;
+ int rate;
+
+ if (offset_hz < HDSP_DDS_OFFSET_MIN ||
+ offset_hz > HDSP_DDS_OFFSET_MAX)
+ return -EINVAL;
+
+ rate = hdsp->system_sample_rate + offset_hz;
+ if (rate <= 0)
+ return -EINVAL;
hdsp_set_dds_value(hdsp, rate);
return 0;
}
@@ -2810,8 +2821,8 @@ static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ct
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
- uinfo->value.integer.min = -5000;
- uinfo->value.integer.max = 5000;
+ uinfo->value.integer.min = HDSP_DDS_OFFSET_MIN;
+ uinfo->value.integer.max = HDSP_DDS_OFFSET_MAX;
return 0;
}
@@ -2833,10 +2844,14 @@ static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl
return -EBUSY;
val = ucontrol->value.integer.value[0];
guard(spinlock_irq)(&hdsp->lock);
- if (val != hdsp_dds_offset(hdsp))
- change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
- else
+ if (val != hdsp_dds_offset(hdsp)) {
+ change = hdsp_set_dds_offset(hdsp, val);
+ if (change < 0)
+ return change;
+ change = 1;
+ } else {
change = 0;
+ }
return change;
}
--
2.25.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] ALSA: hdsp: Fix divide-by-zero in DDS offset control
2026-11-04 8:30 [PATCH] ALSA: hdsp: Fix divide-by-zero in DDS offset control songxiebing
2026-11-04 9:00 ` [PATCH v2] ALSA: hdsp: Validate DDS offset range and propagate errors songxiebing
@ 2026-11-04 10:09 ` Takashi Iwai
1 sibling, 0 replies; 3+ messages in thread
From: Takashi Iwai @ 2026-11-04 10:09 UTC (permalink / raw)
To: songxiebing; +Cc: tiwai, perex, linux-sound, linux-kernel, stable
On Wed, 04 Nov 2026 09:30:45 +0100,
songxiebing wrote:
>
> From: Bob Song <songxiebing@kylinos.cn>
>
> hdsp_set_dds_offset() computes the target rate as
> system_sample_rate + offset_hz without validating the result. A user
> can set the DDS offset to -system_sample_rate through the control API,
> making rate zero and causing div_u64() in hdsp_set_dds_value() to
> divide by zero.
>
> Reject non-positive rates before programming the DDS value.
>
> Fixes: e4b6088c8cf1 ("[ALSA] hdsp - Add support for fine tuning of sample rate support to HDSP 9632")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Bob Song <songxiebing@kylinos.cn>
> ---
> sound/pci/rme9652/hdsp.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
> index 7dce548b9f36..694816f966d2 100644
> --- a/sound/pci/rme9652/hdsp.c
> +++ b/sound/pci/rme9652/hdsp.c
> @@ -2802,6 +2802,9 @@ static int hdsp_dds_offset(struct hdsp *hdsp)
> static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz)
> {
> int rate = hdsp->system_sample_rate + offset_hz;
> +
> + if (rate <= 0)
> + return -EINVAL;
> hdsp_set_dds_value(hdsp, rate);
> return 0;
> }
The caller doesn't check the error case properly.
Please fix the caller side, too.
thanks,
Takashi
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-04 10:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-04 8:30 [PATCH] ALSA: hdsp: Fix divide-by-zero in DDS offset control songxiebing
2026-11-04 9:00 ` [PATCH v2] ALSA: hdsp: Validate DDS offset range and propagate errors songxiebing
2026-11-04 10:09 ` [PATCH] ALSA: hdsp: Fix divide-by-zero in DDS offset control Takashi Iwai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®