]> granicus.if.org Git - libevent/commitdiff
Avoid leaking segment mappings when offset is not a page multiple
authorNick Mathewson <nickm@torproject.org>
Thu, 1 Aug 2013 02:23:16 +0000 (22:23 -0400)
committerNick Mathewson <nickm@torproject.org>
Thu, 1 Aug 2013 02:25:28 +0000 (22:25 -0400)
Found by Bob / Black Hole on the mailing list.

buffer.c

index 860ba0dcd13287b712aa104da9b90036e1855acf..e603be863f01f70441081cf0f930e13462af2edf 100644 (file)
--- 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) {