From d372b3a58001e9693ba85639ceda68ee8f8f32ad Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Wed, 8 Oct 2014 18:47:48 +0200 Subject: [PATCH] check audio parameters returned by the audio drivers, and nicely report driver bugs rather than crashing/misbehaving later if parameters aren't consistent. --- sndiod/siofile.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/sndiod/siofile.c b/sndiod/siofile.c index 97ef87b..ccf15c7 100644 --- a/sndiod/siofile.c +++ b/sndiod/siofile.c @@ -133,6 +133,68 @@ dev_sio_open(struct dev *d) goto bad_close; if (!sio_getpar(d->sio.hdl, &par)) goto bad_close; + +#ifdef DEBUG + /* + * We support any parameters combination exposed by the kernel, + * and we have no other choice than trusting the kernel for + * returning correct parameters. But let's check parameters + * early and nicely report kernel bugs rather than crashing + * later in memset(), malloc() or alike. + */ + + if (par.bits > BITS_MAX) { + log_puts(d->path); + log_puts(": "); + log_putu(par.bits); + log_puts(": unsupported number of bits\n"); + goto bad_close; + } + if (par.bps > SIO_BPS(BITS_MAX)) { + log_puts(d->path); + log_puts(": "); + log_putu(par.bits); + log_puts(": unsupported sample size\n"); + goto bad_close; + } + if ((mode & SIO_PLAY) && par.pchan > NCHAN_MAX) { + log_puts(d->path); + log_puts(": "); + log_putu(par.pchan); + log_puts(": unsupported number of play channels\n"); + goto bad_close; + } + if ((mode & SIO_REC) && par.rchan > NCHAN_MAX) { + log_puts(d->path); + log_puts(": "); + log_putu(par.rchan); + log_puts(": unsupported number of rec channels\n"); + goto bad_close; + } + if (par.bufsz == 0 || par.bufsz > RATE_MAX) { + log_puts(d->path); + log_puts(": "); + log_putu(par.bufsz); + log_puts(": unsupported buffer size\n"); + goto bad_close; + } + if (par.round == 0 || par.round > par.bufsz || + par.bufsz % par.round != 0) { + log_puts(d->path); + log_puts(": "); + log_putu(par.round); + log_puts(": unsupported block size\n"); + goto bad_close; + } + if (par.rate == 0 || par.rate > RATE_MAX) { + log_puts(d->path); + log_puts(": "); + log_putu(par.rate); + log_puts(": unsupported rate\n"); + goto bad_close; + } +#endif + d->par.bits = par.bits; d->par.bps = par.bps; d->par.sig = par.sig;