fix a panic triggerable by anyone with read/write access to the audio

devices.  opening /dev/{dsp,dspW,audio}0 and then opening a different device
from that list and closing it resulted in a panic when any operation is
performed on the first fd.

we prevent this happening by denying the second open unless it uses the same
minor device as the first.

PR:		kern/25519
This commit is contained in:
Cameron Grant 2001-03-13 18:43:22 +00:00
parent 206a3274ef
commit 9a1ec7ebfd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=74216
3 changed files with 11 additions and 1 deletions

View File

@ -129,7 +129,7 @@ struct _pcm_channel {
/* descriptor of audio device */
struct _snddev_info {
pcm_channel *play, *rec, **aplay, **arec, fakechan;
int *ref;
int *ref, *atype;
unsigned playcount, reccount, chancount, maxchans;
snd_mixer *mixer;
u_long magic;

View File

@ -82,6 +82,8 @@ dsp_open(snddev_info *d, int chan, int oflags, int devtype)
if (chan >= d->chancount) return ENODEV;
if ((d->flags & SD_F_SIMPLEX) && (d->ref[chan] > 0)) return EBUSY;
if (d->atype[chan] != 0 && d->atype[chan] != devtype) return EBUSY;
rdch = d->arec[chan];
wrch = d->aplay[chan];
if (oflags & FREAD) {
@ -100,6 +102,7 @@ dsp_open(snddev_info *d, int chan, int oflags, int devtype)
}
} else return EBUSY;
}
d->atype[chan] = devtype;
d->aplay[chan] = wrch;
d->arec[chan] = rdch;
d->ref[chan]++;
@ -161,6 +164,7 @@ dsp_close(snddev_info *d, int chan, int devtype)
}
d->aplay[chan] = NULL;
d->arec[chan] = NULL;
d->atype[chan] = 0;
return 0;
}

View File

@ -361,6 +361,10 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
d->ref = (int *)malloc(sz, M_DEVBUF, M_NOWAIT);
if (!d->ref) goto no;
bzero(d->ref, sz);
d->atype = (int *)malloc(sz, M_DEVBUF, M_NOWAIT);
if (!d->atype) goto no;
bzero(d->atype, sz);
}
if (numplay > 0) {
@ -404,6 +408,7 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
if (d->arec) free(d->arec, M_DEVBUF);
if (d->rec) free(d->rec, M_DEVBUF);
if (d->ref) free(d->ref, M_DEVBUF);
if (d->atype) free(d->atype, M_DEVBUF);
return ENXIO;
}
@ -447,6 +452,7 @@ pcm_unregister(device_t dev)
if (d->arec) free(d->arec, M_DEVBUF);
if (d->rec) free(d->rec, M_DEVBUF);
if (d->ref) free(d->ref, M_DEVBUF);
if (d->atype) free(d->atype, M_DEVBUF);
fkchan_kill(&d->fakechan);