summaryrefslogtreecommitdiff
path: root/buffer.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-07-31 22:23:16 -0400
committerNick Mathewson <nickm@torproject.org>2013-07-31 22:25:28 -0400
commitd4095146aff755f23df579cf0a5a376480ef2b5d (patch)
tree9d69b08fdb014749c47efc6dd93205007efe6bba /buffer.c
parentfbc323b76b338119dad640f733ee100a88435501 (diff)
downloadlibevent-d4095146aff755f23df579cf0a5a376480ef2b5d.tar.gz
Avoid leaking segment mappings when offset is not a page multiple
Found by Bob / Black Hole on the mailing list.
Diffstat (limited to 'buffer.c')
-rw-r--r--buffer.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/buffer.c b/buffer.c
index 860ba0dc..e603be86 100644
--- a/buffer.c
+++ b/buffer.c
@@ -2935,6 +2935,20 @@ err:
return NULL;
}
+#ifdef EVENT__HAVE_MMAP
+static long
+get_page_size(void)
+{
+#ifdef SC_PAGE_SIZE
+ return sysconf(SC_PAGE_SIZE);
+#elif defined(_SC_PAGE_SIZE)
+ return sysconf(_SC_PAGE_SIZE);
+#else
+ return 1;
+#endif
+}
+#endif
+
/* DOCDOC */
/* Requires lock */
static int
@@ -2955,13 +2969,7 @@ evbuffer_file_segment_materialize(struct evbuffer_file_segment *seg)
if (offset) {
/* mmap implementations don't generally like us
* to have an offset that isn't a round */
-#ifdef SC_PAGE_SIZE
- long page_size = sysconf(SC_PAGE_SIZE);
-#elif defined(_SC_PAGE_SIZE)
- long page_size = sysconf(_SC_PAGE_SIZE);
-#else
- long page_size = 1;
-#endif
+ long page_size = get_page_size();
if (page_size == -1)
goto err;
offset_leftover = offset % page_size;
@@ -3073,7 +3081,9 @@ evbuffer_file_segment_free(struct evbuffer_file_segment *seg)
#ifdef _WIN32
CloseHandle(seg->mapping_handle);
#elif defined (EVENT__HAVE_MMAP)
- if (munmap(seg->mapping, seg->length) == -1)
+ off_t offset_leftover;
+ offset_leftover = seg->file_offset % get_page_size();
+ if (munmap(seg->mapping, seg->length + offset_leftover) == -1)
event_warn("%s: munmap failed", __func__);
#endif
} else if (seg->contents) {