diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2020-06-12 15:40:19 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2020-06-12 15:40:19 +0000 |
commit | 5b2e18a31a0d18522b6b22c14c11b783cf1bac1a (patch) | |
tree | 0dc6e1cef669f9c70b52b9818d539589c10f8b0b /usr.bin/sndiod | |
parent | f19dafd86bd5567b8f7d4eb4b6d7b7597267be01 (diff) |
On error, drop clients and close the device only if it's still open
Fixes crashes when USB devices are disconnected, caused by an attempt
to close the already closed device: it was closed once when its ref
counter drops to zero (after the last client is disconnected) and once
with an explicit call to dev_close() on the error code-path.
Diffstat (limited to 'usr.bin/sndiod')
-rw-r--r-- | usr.bin/sndiod/dev.c | 11 | ||||
-rw-r--r-- | usr.bin/sndiod/dev.h | 4 | ||||
-rw-r--r-- | usr.bin/sndiod/midi.c | 9 | ||||
-rw-r--r-- | usr.bin/sndiod/midi.h | 3 | ||||
-rw-r--r-- | usr.bin/sndiod/miofile.c | 4 | ||||
-rw-r--r-- | usr.bin/sndiod/siofile.c | 6 |
6 files changed, 20 insertions, 17 deletions
diff --git a/usr.bin/sndiod/dev.c b/usr.bin/sndiod/dev.c index 9515664107c..fe224a7f6a3 100644 --- a/usr.bin/sndiod/dev.c +++ b/usr.bin/sndiod/dev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.c,v 1.71 2020/04/24 11:33:28 ratchov Exp $ */ +/* $OpenBSD: dev.c,v 1.72 2020/06/12 15:40:18 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -59,7 +59,6 @@ struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int, void dev_adjpar(struct dev *, int, int, int); int dev_allocbufs(struct dev *); int dev_open(struct dev *); -void dev_exitall(struct dev *); void dev_freebufs(struct dev *); void dev_close(struct dev *); int dev_ref(struct dev *); @@ -1193,10 +1192,10 @@ dev_open(struct dev *d) } /* - * Force all slots to exit + * Force all slots to exit and close device, called after an error */ void -dev_exitall(struct dev *d) +dev_abort(struct dev *d) { int i; struct slot *s; @@ -1214,6 +1213,9 @@ dev_exitall(struct dev *d) c->ops->exit(c->arg); c->ops = NULL; } + + if (d->pstate != DEV_CFG) + dev_close(d); } /* @@ -1249,7 +1251,6 @@ dev_close(struct dev *d) { struct ctl *c; - dev_exitall(d); d->pstate = DEV_CFG; dev_sio_close(d); dev_freebufs(d); diff --git a/usr.bin/sndiod/dev.h b/usr.bin/sndiod/dev.h index 5e1521f3830..0c600d793e1 100644 --- a/usr.bin/sndiod/dev.h +++ b/usr.bin/sndiod/dev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.h,v 1.25 2020/04/16 12:26:55 ratchov Exp $ */ +/* $OpenBSD: dev.h,v 1.26 2020/06/12 15:40:18 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -260,7 +260,7 @@ struct dev { extern struct dev *dev_list; void dev_log(struct dev *); -void dev_close(struct dev *); +void dev_abort(struct dev *); int dev_reopen(struct dev *); struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); diff --git a/usr.bin/sndiod/midi.c b/usr.bin/sndiod/midi.c index d3bd018de32..a739cb474e9 100644 --- a/usr.bin/sndiod/midi.c +++ b/usr.bin/sndiod/midi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.c,v 1.24 2020/04/25 05:03:54 ratchov Exp $ */ +/* $OpenBSD: midi.c,v 1.25 2020/06/12 15:40:18 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -563,7 +563,7 @@ port_open(struct port *c) } void -port_exitall(struct port *c) +port_abort(struct port *c) { int i; struct midi *ep; @@ -574,6 +574,9 @@ port_exitall(struct port *c) (c->midi->txmask & ep->self)) ep->ops->exit(ep->arg); } + + if (c->state != PORT_CFG) + port_close(c); } int @@ -588,8 +591,6 @@ port_close(struct port *c) #endif c->state = PORT_CFG; port_mio_close(c); - - port_exitall(c); return 1; } diff --git a/usr.bin/sndiod/midi.h b/usr.bin/sndiod/midi.h index bdcc2b7d7e0..8c51a6e9975 100644 --- a/usr.bin/sndiod/midi.h +++ b/usr.bin/sndiod/midi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.h,v 1.12 2020/04/25 05:03:54 ratchov Exp $ */ +/* $OpenBSD: midi.h,v 1.13 2020/06/12 15:40:18 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -124,5 +124,6 @@ void port_done(struct port *); void port_drain(struct port *); int port_close(struct port *); int port_reopen(struct port *); +void port_abort(struct port *); #endif /* !defined(MIDI_H) */ diff --git a/usr.bin/sndiod/miofile.c b/usr.bin/sndiod/miofile.c index bf6feb8071b..6da4ecdb996 100644 --- a/usr.bin/sndiod/miofile.c +++ b/usr.bin/sndiod/miofile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: miofile.c,v 1.6 2020/01/23 05:40:09 ratchov Exp $ */ +/* $OpenBSD: miofile.c,v 1.7 2020/06/12 15:40:18 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -188,5 +188,5 @@ port_mio_hup(void *arg) struct port *p = arg; if (!port_reopen(p)) - port_close(p); + port_abort(p); } diff --git a/usr.bin/sndiod/siofile.c b/usr.bin/sndiod/siofile.c index a33558c81eb..4cc0be02a49 100644 --- a/usr.bin/sndiod/siofile.c +++ b/usr.bin/sndiod/siofile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: siofile.c,v 1.19 2020/04/24 11:33:28 ratchov Exp $ */ +/* $OpenBSD: siofile.c,v 1.20 2020/06/12 15:40:18 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -84,7 +84,7 @@ dev_sio_timeout(void *arg) dev_log(d); log_puts(": watchdog timeout\n"); - dev_close(d); + dev_abort(d); } /* @@ -641,5 +641,5 @@ dev_sio_hup(void *arg) } #endif if (!dev_reopen(d)) - dev_close(d); + dev_abort(d); } |