diff options
author | 2010-06-25 07:32:05 +0000 | |
---|---|---|
committer | 2010-06-25 07:32:05 +0000 | |
commit | fc594be013556c6b052d1d29d360bccd4e1f55ff (patch) | |
tree | e49579281a0e3fee9ade453947de28903109d665 | |
parent | bz#1750: fix requirement for /dev/null inside ChrootDirectory for (diff) | |
download | wireguard-openbsd-fc594be013556c6b052d1d29d360bccd4e1f55ff.tar.xz wireguard-openbsd-fc594be013556c6b052d1d29d360bccd4e1f55ff.zip |
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, |