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
This commit is contained in:
Dag-Erling Smørgrav 2005-10-30 10:03:11 +00:00
parent c0498352c1
commit 85cc3851ff
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151878

View File

@ -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);
}