diff options
author | des <des@FreeBSD.org> | 2005-10-30 10:03:11 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2005-10-30 10:03:11 +0000 |
commit | 90d04d11a4c99e9273edeace4b5b5e7582cb88a1 (patch) | |
tree | a6e9ebd4bb79e52a442ff68ab0ac20f216cf21c1 | |
parent | 6350b203b922f24ad697698b3d7453d349b74aaf (diff) | |
download | FreeBSD-src-90d04d11a4c99e9273edeace4b5b5e7582cb88a1.zip FreeBSD-src-90d04d11a4c99e9273edeace4b5b5e7582cb88a1.tar.gz |
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
-rw-r--r-- | sys/dev/sound/pcm/dsp.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 3309ead..3cb09d7 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); } |