From 85cc3851ff1eda6f84af9297b294e3289c3ca2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sun, 30 Oct 2005 10:03:11 +0000 Subject: [PATCH] Add some safeguards to AIOSFMT: - Return EINVAL if play_format or rec_format is set but the corresponding sample rate is 0. - Don't try to set the playback or recording format to 0. Previously, issuing an AIOSFMT ioctl with an all-zeroes snd_chan_param would trigger a KASSERT in chn_fmtchain(); I'm unsure about the effects on a kernel without INVARIANTS. After this commit, issuing AIOSFMT with an all-zeroes snd_chan_param is equivalent to issuing AIOGFMT. MFC after: 2 weeks --- sys/dev/sound/pcm/dsp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 3309eaddfa9b..3cb09d7f5047 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -512,9 +512,15 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread * { snd_chan_param *p = (snd_chan_param *)arg; + if (cmd == AIOSFMT && + ((p->play_format != 0 && p->play_rate == 0) || + (p->rec_format != 0 && p->rec_rate == 0))) { + ret = EINVAL; + break; + } if (wrch) { CHN_LOCK(wrch); - if (cmd == AIOSFMT) { + if (cmd == AIOSFMT && p->play_format != 0) { chn_setformat(wrch, p->play_format); chn_setspeed(wrch, p->play_rate); } @@ -527,7 +533,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread * } if (rdch) { CHN_LOCK(rdch); - if (cmd == AIOSFMT) { + if (cmd == AIOSFMT && p->rec_format != 0) { chn_setformat(rdch, p->rec_format); chn_setspeed(rdch, p->rec_rate); }