diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2014-04-17 11:40:09 +0800 |
---|---|---|
committer | Jeremy Kerr <jk@ozlabs.org> | 2014-04-17 11:50:39 +0800 |
commit | 8245f2555d8a253238be888cf3e5693a2e7cbefc (patch) | |
tree | 20a4b6a0946d37d5fcd5f5384163217e8bd180c4 /discover/udev.c | |
parent | a1fb38f17bfa60aac89d0dd21dd8ccc739d794bf (diff) | |
download | petitboot-8245f2555d8a253238be888cf3e5693a2e7cbefc.zip petitboot-8245f2555d8a253238be888cf3e5693a2e7cbefc.tar.gz |
discover/udev: fix double free on udev_init failures
If the udev monitor or enumerate functions fail, we'll call the
udev_unref and udev_monitor_unref functions twice: once in the cleanup
path and once in the talloc destructor.
This change moves all cleanup to the talloc destructor, so we only do
the unrefs once.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'discover/udev.c')
-rw-r--r-- | discover/udev.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/discover/udev.c b/discover/udev.c index 9e1a5ce..00b6df7 100644 --- a/discover/udev.c +++ b/discover/udev.c @@ -41,11 +41,15 @@ static int udev_destructor(void *p) { struct pb_udev *udev = p; - udev_monitor_unref(udev->monitor); - udev->monitor = NULL; + if (udev->monitor) { + udev_monitor_unref(udev->monitor); + udev->monitor = NULL; + } - udev_unref(udev->udev); - udev->udev = NULL; + if (udev->udev) { + udev_unref(udev->udev); + udev->udev = NULL; + } return 0; } @@ -426,7 +430,7 @@ struct pb_udev *udev_init(struct device_handler *handler, struct pb_udev *udev; int result; - udev = talloc(handler, struct pb_udev); + udev = talloc_zero(handler, struct pb_udev); talloc_set_destructor(udev, udev_destructor); udev->handler = handler; @@ -434,7 +438,7 @@ struct pb_udev *udev_init(struct device_handler *handler, if (!udev->udev) { pb_log("udev_new failed\n"); - goto fail_new; + goto fail; } udev_set_userdata(udev->udev, udev); @@ -443,11 +447,11 @@ struct pb_udev *udev_init(struct device_handler *handler, result = udev_setup_monitor(udev->udev, &udev->monitor); if (result) - goto fail_monitor; + goto fail; result = udev_enumerate(udev->udev); if (result) - goto fail_enumerate; + goto fail; waiter_register_io(waitset, udev_monitor_get_fd(udev->monitor), WAIT_IN, udev_process, udev->monitor); @@ -456,11 +460,7 @@ struct pb_udev *udev_init(struct device_handler *handler, return udev; -fail_monitor: - udev_monitor_unref(udev->monitor); -fail_enumerate: - udev_unref(udev->udev); -fail_new: +fail: talloc_free(udev); return NULL; } |