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:
parent
206a3274ef
commit
9a1ec7ebfd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=74216
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user