diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2010-06-25 07:32:06 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2010-06-25 07:32:06 +0000 |
commit | 5391d7a0f83d8a9499059a78ad8939ed9e58757f (patch) | |
tree | 057ae2e61c99c87fb18ee140738fddb1ac23d4d3 | |
parent | 3bc361ce722cd2e583d357787c855db75cb54b18 (diff) |
don't attempt to drain devices after they are destroyed, which
results in a use after free(). Catched by jakemsr@ with MALLOC_OPTIONS=J
-rw-r--r-- | usr.bin/aucat/aucat.c | 10 | ||||
-rw-r--r-- | usr.bin/aucat/dev.c | 15 | ||||
-rw-r--r-- | usr.bin/aucat/dev.h | 3 |
3 files changed, 20 insertions, 8 deletions
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c index 3db6b56a4da..42f4fc3cea9 100644 --- a/usr.bin/aucat/aucat.c +++ b/usr.bin/aucat/aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aucat.c,v 1.95 2010/06/20 11:32:54 ratchov Exp $ */ +/* $OpenBSD: aucat.c,v 1.96 2010/06/25 07:32:05 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -817,14 +817,16 @@ aucat_main(int argc, char **argv) fatal: if (l_flag) file_close(&listen->file); - while (dev_list) - dev_del(dev_list); - /* * give a chance to drain */ + for (d = dev_list; d != NULL; d = d->next) + dev_drain(d); while (file_poll()) ; /* nothing */ + + while (dev_list) + dev_del(dev_list); filelist_done(); if (l_flag) { if (rmdir(base) < 0 && errno != ENOTEMPTY && errno != EPERM) diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c index 5815d84b733..0b5005c4356 100644 --- a/usr.bin/aucat/dev.c +++ b/usr.bin/aucat/dev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.c,v 1.59 2010/06/05 16:14:44 ratchov Exp $ */ +/* $OpenBSD: dev.c,v 1.60 2010/06/25 07:32:05 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -533,6 +533,16 @@ dev_close(struct dev *d) } /* + * Unless the device is already in process of closing, request it to close + */ +void +dev_drain(struct dev *d) +{ + if (d->pstate != DEV_CLOSED) + dev_close(d); +} + +/* * Free the device */ void @@ -540,8 +550,7 @@ dev_del(struct dev *d) { struct dev **p; - if (d->pstate != DEV_CLOSED) - dev_close(d); + dev_drain(d); for (p = &dev_list; *p != d; p = &(*p)->next) { #ifdef DEBUG if (*p == NULL) { diff --git a/usr.bin/aucat/dev.h b/usr.bin/aucat/dev.h index ab8f412fd23..ca34ea0cc5b 100644 --- a/usr.bin/aucat/dev.h +++ b/usr.bin/aucat/dev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.h,v 1.25 2010/06/05 16:00:52 ratchov Exp $ */ +/* $OpenBSD: dev.h,v 1.26 2010/06/25 07:32:05 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -59,6 +59,7 @@ int dev_ref(struct dev *); void dev_unref(struct dev *); void dev_del(struct dev *); void dev_wakeup(struct dev *); +void dev_drain(struct dev *); struct dev *dev_new_thru(void); struct dev *dev_new_loop(struct aparams *, struct aparams *, unsigned); struct dev *dev_new_sio(char *, unsigned, |