summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2006-11-26 15:24:35 +0000
committerBrad Smith <brad@cvs.openbsd.org>2006-11-26 15:24:35 +0000
commit4b637a3eacaa25dbf777e1d7e1b3337c0c34ccc9 (patch)
tree59852ecfcab12fc466c1e1a4e6aed795947bf475
parentcbb9db8873092c40a728e0347abf1d619ebf1101 (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.c50
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;