diff options
author | guenther <> | 2022-06-30 17:15:48 +0000 |
---|---|---|
committer | guenther <> | 2022-06-30 17:15:48 +0000 |
commit | 77f0574b7c2b37a3c137d20f6ad687362c8da9a0 (patch) | |
tree | 2425f35436d2313336db8896e3fffeb6c8cf530d | |
parent | 29cede2c0ebae841864f6d6a7011218f23f586b9 (diff) | |
download | openbsd-77f0574b7c2b37a3c137d20f6ad687362c8da9a0.tar.gz openbsd-77f0574b7c2b37a3c137d20f6ad687362c8da9a0.tar.bz2 openbsd-77f0574b7c2b37a3c137d20f6ad687362c8da9a0.zip |
To figure our whether a large allocation can be grown into the
following page(s) we've been first mquery()ing for it, mmapp()ing
w/o MAP_FIXED if available, and then munmap()ing if there was a
race. Instead, just try it directly with
mmap(MAP_FIXED | __MAP_NOREPLACE)
tested in snaps for weeks
ok deraadt@
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 14 |
1 files changed, 2 insertions, 12 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index a700087534..b12c89aca0 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: malloc.c,v 1.273 2022/02/26 16:14:42 otto Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.274 2022/06/30 17:15:48 guenther Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> | 3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> |
4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> | 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> |
@@ -100,9 +100,6 @@ | |||
100 | #define MMAPA(a,sz,f) mmap((a), (sz), PROT_READ | PROT_WRITE, \ | 100 | #define MMAPA(a,sz,f) mmap((a), (sz), PROT_READ | PROT_WRITE, \ |
101 | MAP_ANON | MAP_PRIVATE | (f), -1, 0) | 101 | MAP_ANON | MAP_PRIVATE | (f), -1, 0) |
102 | 102 | ||
103 | #define MQUERY(a,sz,f) mquery((a), (sz), PROT_READ | PROT_WRITE, \ | ||
104 | MAP_ANON | MAP_PRIVATE | MAP_FIXED | (f), -1, 0) | ||
105 | |||
106 | struct region_info { | 103 | struct region_info { |
107 | void *p; /* page; low bits used to mark chunks */ | 104 | void *p; /* page; low bits used to mark chunks */ |
108 | uintptr_t size; /* size for pages, or chunk_info pointer */ | 105 | uintptr_t size; /* size for pages, or chunk_info pointer */ |
@@ -1687,11 +1684,7 @@ orealloc(struct dir_info **argpool, void *p, size_t newsz, void *f) | |||
1687 | size_t needed = rnewsz - roldsz; | 1684 | size_t needed = rnewsz - roldsz; |
1688 | 1685 | ||
1689 | STATS_INC(pool->cheap_realloc_tries); | 1686 | STATS_INC(pool->cheap_realloc_tries); |
1690 | q = MQUERY(hint, needed, pool->mmap_flag); | 1687 | q = MMAPA(hint, needed, MAP_FIXED | __MAP_NOREPLACE | pool->mmap_flag); |
1691 | if (q == hint) | ||
1692 | q = MMAPA(hint, needed, pool->mmap_flag); | ||
1693 | else | ||
1694 | q = MAP_FAILED; | ||
1695 | if (q == hint) { | 1688 | if (q == hint) { |
1696 | STATS_ADD(pool->malloc_used, needed); | 1689 | STATS_ADD(pool->malloc_used, needed); |
1697 | if (pool->malloc_junk == 2) | 1690 | if (pool->malloc_junk == 2) |
@@ -1709,9 +1702,6 @@ orealloc(struct dir_info **argpool, void *p, size_t newsz, void *f) | |||
1709 | STATS_INC(pool->cheap_reallocs); | 1702 | STATS_INC(pool->cheap_reallocs); |
1710 | ret = p; | 1703 | ret = p; |
1711 | goto done; | 1704 | goto done; |
1712 | } else if (q != MAP_FAILED) { | ||
1713 | if (munmap(q, needed)) | ||
1714 | wrterror(pool, "munmap %p", q); | ||
1715 | } | 1705 | } |
1716 | } | 1706 | } |
1717 | } else if (rnewsz < roldsz) { | 1707 | } else if (rnewsz < roldsz) { |