diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2006-11-26 15:24:35 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2006-11-26 15:24:35 +0000 |
commit | 4b637a3eacaa25dbf777e1d7e1b3337c0c34ccc9 (patch) | |
tree | 59852ecfcab12fc466c1e1a4e6aed795947bf475 | |
parent | cbb9db8873092c40a728e0347abf1d619ebf1101 (diff) |
fail without leaking memory when poll set extension fails.
From Niels Provos via the libevent SVN
ok deraadt@
-rw-r--r-- | lib/libevent/poll.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/lib/libevent/poll.c b/lib/libevent/poll.c index 2e76dfc6613..cd0eabd43e1 100644 --- a/lib/libevent/poll.c +++ b/lib/libevent/poll.c @@ -1,4 +1,4 @@ -/* $OpenBSD: poll.c,v 1.12 2006/03/30 06:32:36 brad Exp $ */ +/* $OpenBSD: poll.c,v 1.13 2006/11/26 15:24:34 brad Exp $ */ /* * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu> @@ -235,29 +235,48 @@ poll_add(void *arg, struct event *ev) poll_check_ok(pop); if (pop->nfds + 1 >= pop->event_count) { + struct pollfd *tmp_event_set; + struct event **tmp_event_r_back; + struct event **tmp_event_w_back; + int tmp_event_count; + if (pop->event_count < 32) - pop->event_count = 32; + tmp_event_count = 32; else - pop->event_count *= 2; + tmp_event_count = pop->event_count * 2; /* We need more file descriptors */ - pop->event_set = realloc(pop->event_set, - pop->event_count * sizeof(struct pollfd)); - if (pop->event_set == NULL) { + tmp_event_set = realloc(pop->event_set, + tmp_event_count * sizeof(struct pollfd)); + if (tmp_event_set == NULL) { event_warn("realloc"); return (-1); } - pop->event_r_back = realloc(pop->event_r_back, - pop->event_count * sizeof(struct event *)); - pop->event_w_back = realloc(pop->event_w_back, - pop->event_count * sizeof(struct event *)); - if (pop->event_r_back == NULL || - pop->event_w_back == NULL) { + pop->event_set = tmp_event_set; + + tmp_event_r_back = realloc(pop->event_r_back, + tmp_event_count * sizeof(struct event *)); + if (tmp_event_r_back == NULL) { + /* event_set overallocated; that's okay. */ event_warn("realloc"); return (-1); } + pop->event_r_back = tmp_event_r_back; + + tmp_event_w_back = realloc(pop->event_w_back, + tmp_event_count * sizeof(struct event *)); + if (tmp_event_w_back == NULL) { + /* event_set and event_r_back overallocated; that's + * okay. */ + event_warn("realloc"); + return (-1); + } + pop->event_w_back = tmp_event_w_back; + + pop->event_count = tmp_event_count; } if (ev->ev_fd >= pop->fd_count) { + int *tmp_idxplus1_by_fd; int new_count; if (pop->fd_count < 32) new_count = 32; @@ -265,12 +284,13 @@ poll_add(void *arg, struct event *ev) new_count = pop->fd_count * 2; while (new_count <= ev->ev_fd) new_count *= 2; - pop->idxplus1_by_fd = - realloc(pop->idxplus1_by_fd, new_count*sizeof(int)); - if (pop->idxplus1_by_fd == NULL) { + tmp_idxplus1_by_fd = + realloc(pop->idxplus1_by_fd, new_count * sizeof(int)); + if (tmp_idxplus1_by_fd == NULL) { event_warn("realloc"); return (-1); } + pop->idxplus1_by_fd = tmp_idxplus1_by_fd; memset(pop->idxplus1_by_fd + pop->fd_count, 0, sizeof(int)*(new_count - pop->fd_count)); pop->fd_count = new_count; |