Commit graph

10 commits

Author SHA1 Message Date
Vitaly Vul
ee67dd75e2 mmap: fix calculation of is_private_anonymous variable
Currently is_private_anonymous is calculated as true if _either_
MAP_PRIVATE or MAP_ANONYMOUS is set, which is a mistake.
According to Documentation/vm/ksm.txt, "KSM only merges anonymous
(private) pages, never pagecache (file) pages". MAP_PRIVATE can
still be set on file cache pages so in order to not redundantly
set MADV_MERGEABLE on pages that are not fitted for it, both
MAP_PRIVATE and MAP_ANONYMOUS should be set.

Along with this fix, add an extra check that the mapped page is
not a stack page before setting MADV_MERGEABLE for it. Stack pages
change too quickly and always end up in KSM 'page_volatile' list.

Change-Id: If4954142852f17cc61f02985ea1cb625a7f3dec6
2015-11-20 09:16:59 -08:00
Daniel Micay
c22a7de798 extend the PTRDIFF_MAX size check to mremap
This removes another way to obtain objects larger than PTRDIFF_MAX. The
only known remaining hole is now jemalloc's merging of virtual memory
spans.

Technically this could be wrapped in an __LP64__ ifndef since it can't
occur on 64-bit due to the 1:1 split. It doesn't really matter either
way.

Change-Id: Iab2af242b775bc98a59421994d87aca0433215bd
2015-11-19 08:57:47 -05:00
Daniel Micay
706186d266 fix PTRDIFF_MAX check in the 32-bit mmap wrapper
It wasn't making use of the page-rounded size.

Change-Id: I911345fcfd6419a4dbc18a4622b42e1b76729abb
2015-11-03 05:30:29 -05:00
Daniel Micay
5ca66528c5 make mmap fail on requests larger than PTRDIFF_MAX
Allocations larger than PTRDIFF_MAX can be successfully created on
32-bit with a 3:1 split, or in 32-bit processes running on 64-bit.

Allowing these allocations to succeed is dangerous, as it introduces
overflows for `end - start` and isn't compatible with APIs (mis)using
ssize_t to report either the size or an error. POSIX is guilty of this,
as are many other Android APIs. LLVM even considers the `ptr + size`
case to be undefined, as all pointer arithmetic compiles down to signed
operations and overflow is treated as undefined for standard C pointer
arithmetic (GNU C `void *` arithmetic works differently).

This also prevents dlmalloc from allocating > PTRDIFF_MAX as it doesn't
merge mappings like jemalloc. A similar check will need to be added in
jemalloc's code path for huge allocations.

The musl libc implementation also performs this sanity check.

Change-Id: I5f849543f94a39719f5d27b00cef3079bb5933e9
2015-09-12 01:52:12 -04:00
Elliott Hughes
9bd9b7dd20 If the kernel doesn't have MADV_MERGEABLE, stop asking for it.
Note that a dynamically-linked binary will still probably see two attempts ---
one by the dynamic linker (which will set its copy of the flag so it won't try
again) and then one by the executable itself (which gets a new uninitialized
copy of the flag).

Change-Id: Id6b7e47780f0f24d2ca0384a75373f4824fa8f12
2014-03-03 11:54:21 -08:00
Elliott Hughes
431166d995 Fix 32-bit mmap/mmap64 handling of negative offsets.
We don't actually need to worry about sign extension if we reject
negative values ourselves. Previously it was possible to come up
with negative but aligned values that we would pass to the kernel;
in the case of mmap (as opposed to mmap64) we'd incorrectly turn
those into large positive offsets.

Change-Id: I2aa583e0f892d59bb77429aea8730b72db32dcb0
2014-01-27 16:36:56 -08:00
Elliott Hughes
99868904fe Avoid sign extension in 32-bit mmap.
Change-Id: I2a77925f62f381a0b34648c3db8154a55dd80c46
2013-12-20 18:17:34 -08:00
Daniel Leung
afcc0cccda Add mmap64()
This adds mmap64() to bionic so that it is possible to have
large offset passed to kernel. However, the syscall mechanism
only passes 32-bit number to kernel. So effectively, the
largest offset that can be passed is about 43 bits (since
offset is signed, and the number passed to kernel is number
of pages (page size == 4K => 12 bits)).

Change-Id: Ib54f4e9b54acb6ef8b0324f3b89c9bc810b07281
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2013-09-19 14:11:26 -07:00
Elliott Hughes
e320a8c780 Avoid sign extension of the mmap offset.
off_t is signed to support seeking backwards, but that's a liability
when using off_t to represent a subset of a file.

Change-Id: I2a3615166eb16212347eb47f1242e3bfb93c2022
2013-07-25 10:15:07 -07:00
Elliott Hughes
107cdd406b Prevent the madvise(MADV_MERGEABLE) mmap hack from affecting errno.
Bug: 9889616
Change-Id: I4a7323e0ae5aeb5cbe0da1b2bc7501d83b3a2aa4
2013-07-17 13:12:26 -07:00
Renamed from libc/bionic/mmap.c (Browse further)