-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Fix invalid memory write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked #15117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix invalid memory write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked #15117
Conversation
…geAllocator::AllocateLocked
return static_cast<T*>(LockedPoolManager::Instance().alloc(sizeof(T) * n)); | ||
T* allocation = static_cast<T*>(LockedPoolManager::Instance().alloc(sizeof(T) * n)); | ||
if (!allocation) { | ||
throw std::bad_alloc(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe propagate errno info?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think bad_alloc
have any parameterized ctor:s?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed - I guess the other option would be to log it in the allocate
method. (nit only)
@@ -248,6 +248,9 @@ void *PosixLockedPageAllocator::AllocateLocked(size_t len, bool *lockingSuccess) | |||
void *addr; | |||
len = align_up(len, page_size); | |||
addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |||
if (addr == MAP_FAILED) { | |||
return nullptr; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Judging from leveldb's handling, and the mmap docs, the null value case is negligible:
bitcoin/src/leveldb/util/env_posix.cc
Lines 367 to 372 in 9c71998
void* base = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); | |
if (base != MAP_FAILED) { | |
*result = new PosixMmapReadableFile(fname, base, size, &mmap_limit_); | |
} else { | |
s = IOError(fname, errno); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to parse TBH: are you suggesting a change here? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just that the if (addr)
is strictly unnecessary.
Concept ACK |
TIL. Always thought it returned
utACK ca126d4 |
Concept ACK. I too assumed mmap returned NULL on failure. |
Concept ACK - good spot! |
…n PosixLockedPageAllocator::AllocateLocked ca126d4 Fix out-of-bounds write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked (practicalswift) Pull request description: `mmap(...)` returns `MAP_FAILED` (`(void *) -1`) in case of allocation failure. `PosixLockedPageAllocator::AllocateLocked(...)` did not check for allocation failures prior to this PR. Instead the invalid memory address `(void *) -1` (`0xffffffffffffffff`) was passed to the caller as if it was a valid address. After some operations the address is wrapped around from `0xffffffffffffffff` to `0x00000003ffdf` (`0xffffffffffffffff + 262112 == 0x00000003ffdf`); The resulting address `0x00000003ffdf` is then written to. Before this patch (with failing `mmap` call): ``` $ src/bitcoind … 2019-01-06T16:28:14Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation 2019-01-06T16:28:14Z Using RdRand as an additional entropy source Segmentation fault (core dumped) ``` Before this patch (under `valgrind` with failing `mmap` call): ``` $ valgrind src/bitcoind … 2019-01-06T16:28:51Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation ==17812== Invalid write of size 1 ==17812== at 0x500B7E: void __gnu_cxx::new_allocator<unsigned char>::construct<unsigned char>(unsigned char*) (new_allocator.h:136) ==17812== by 0x500B52: _ZNSt16allocator_traitsI16secure_allocatorIhEE12_S_constructIhJEEENSt9enable_ifIXsr6__and_INS2_18__construct_helperIT_JDpT0_EE4typeEEE5valueEvE4typeERS1_PS6_DpOS7_ (alloc_traits.h:243) ==17812== by 0x500B22: _ZNSt16allocator_traitsI16secure_allocatorIhEE9constructIhJEEEDTcl12_S_constructfp_fp0_spclsr3stdE7forwardIT0_Efp1_EEERS1_PT_DpOS4_ (alloc_traits.h:344) ==17812== by 0x500982: unsigned char* std::__uninitialized_default_n_a<unsigned char*, unsigned long, secure_allocator<unsigned char> >(unsigned char*, unsigned long, secure_allocator<unsigned char>&) (stl_uninitialized.h:631) ==17812== by 0x60BFC2: std::vector<unsigned char, secure_allocator<unsigned char> >::_M_default_initialize(unsigned long) (stl_vector.h:1347) ==17812== by 0x60BD86: std::vector<unsigned char, secure_allocator<unsigned char> >::vector(unsigned long, secure_allocator<unsigned char> const&) (stl_vector.h:285) ==17812== by 0x60BB55: ECC_Start() (key.cpp:351) ==17812== by 0x16AC90: AppInitSanityChecks() (init.cpp:1162) ==17812== by 0x15BAC9: AppInit(int, char**) (bitcoind.cpp:138) ==17812== by 0x15B6C8: main (bitcoind.cpp:201) ==17812== Address 0x3ffdf is not stack'd, malloc'd or (recently) free'd … Segmentation fault (core dumped) ``` After this patch (with failing `mmap` call): ``` $ src/bitcoind … 2019-01-06T15:50:18Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation 2019-01-06T15:50:18Z Using RdRand as an additional entropy source 2019-01-06T15:50:18Z ************************ EXCEPTION: St9bad_alloc std::bad_alloc bitcoin in AppInit() ************************ EXCEPTION: St9bad_alloc std::bad_alloc bitcoin in AppInit() 2019-01-06T15:50:18Z Shutdown: In progress... 2019-01-06T15:50:18Z Shutdown: done ``` To simulate the failing `mmap` call apply the following to `master`: ```diff diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index 8d577cf..ce79e569b 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -247,7 +247,8 @@ void *PosixLockedPageAllocator::AllocateLocked(size_t len, bool *lockingSuccess) { void *addr; len = align_up(len, page_size); - addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + // addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + addr = MAP_FAILED; if (addr) { *lockingSuccess = mlock(addr, len) == 0; } ``` Tree-SHA512: 66947f5fc0fbb19afb3e1edbd51df07df9d16b77018cff3d48d30f378a53d6a0dc62bc36622b3966b7e374e61edbcca114ef4ac8ae8d725022c1a597edcbf7c7
Locked memory manager Add a pool for locked memory chunks, replacing `LockedPageManager`. Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#8321 - bitcoin/bitcoin#8753 - bitcoin/bitcoin#9063 - bitcoin/bitcoin#9070 - bitcoin/bitcoin#11385 - bitcoin/bitcoin#12048 - Excludes change to benchmark. - bitcoin/bitcoin#15117 - bitcoin/bitcoin#16161 - Excludes Travis CI changes. - Includes change from bitcoin/bitcoin#13163 - bitcoin/bitcoin#15600 - bitcoin/bitcoin#18443 - Assorted small changes from: - bitcoin/bitcoin#9233 - bitcoin/bitcoin#10483 - bitcoin/bitcoin#10645 - bitcoin/bitcoin#10969 - bitcoin/bitcoin#11351 - bitcoin/bitcoin#19111 - Excludes change to `src/rpc/server.cpp` - bitcoin/bitcoin#9804 - Only the commit for `src/key.cpp` - bitcoin/bitcoin#9598
…geAllocator::AllocateLocked Summary: PR description: > mmap(...) returns MAP_FAILED ((void *) -1) in case of allocation failure. > > PosixLockedPageAllocator::AllocateLocked(...) did not check for allocation failures prior to this PR. > > Instead the invalid memory address (void *) -1 (0xffffffffffffffff) was passed to the caller as if it was a valid address. > > After some operations the address is wrapped around from 0xffffffffffffffff to 0x00000003ffdf (0xffffffffffffffff + 262112 == 0x00000003ffdf); > > The resulting address 0x00000003ffdf is then written to. > > Before this patch (with failing mmap call): > > ``` > $ src/bitcoind > … > 2019-01-06T16:28:14Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation > 2019-01-06T16:28:14Z Using RdRand as an additional entropy source > Segmentation fault (core dumped) > ``` > > After this patch (with failing mmap call): > ``` > $ src/bitcoind > … > 2019-01-06T15:50:18Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation > 2019-01-06T15:50:18Z Using RdRand as an additional entropy source > 2019-01-06T15:50:18Z > > ************************ > EXCEPTION: St9bad_alloc > std::bad_alloc > bitcoin in AppInit() > > > > ************************ > EXCEPTION: St9bad_alloc > std::bad_alloc > bitcoin in AppInit() > > 2019-01-06T15:50:18Z Shutdown: In progress... > 2019-01-06T15:50:18Z Shutdown: done > ``` This is a backport of Core [[bitcoin/bitcoin#15117 | PR15117]] Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D8354
…(...) in PosixLockedPageAllocator::AllocateLocked ca126d4 Fix out-of-bounds write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked (practicalswift) Pull request description: `mmap(...)` returns `MAP_FAILED` (`(void *) -1`) in case of allocation failure. `PosixLockedPageAllocator::AllocateLocked(...)` did not check for allocation failures prior to this PR. Instead the invalid memory address `(void *) -1` (`0xffffffffffffffff`) was passed to the caller as if it was a valid address. After some operations the address is wrapped around from `0xffffffffffffffff` to `0x00000003ffdf` (`0xffffffffffffffff + 262112 == 0x00000003ffdf`); The resulting address `0x00000003ffdf` is then written to. Before this patch (with failing `mmap` call): ``` $ src/bitcoind … 2019-01-06T16:28:14Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation 2019-01-06T16:28:14Z Using RdRand as an additional entropy source Segmentation fault (core dumped) ``` Before this patch (under `valgrind` with failing `mmap` call): ``` $ valgrind src/bitcoind … 2019-01-06T16:28:51Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation ==17812== Invalid write of size 1 ==17812== at 0x500B7E: void __gnu_cxx::new_allocator<unsigned char>::construct<unsigned char>(unsigned char*) (new_allocator.h:136) ==17812== by 0x500B52: _ZNSt16allocator_traitsI16secure_allocatorIhEE12_S_constructIhJEEENSt9enable_ifIXsr6__and_INS2_18__construct_helperIT_JDpT0_EE4typeEEE5valueEvE4typeERS1_PS6_DpOS7_ (alloc_traits.h:243) ==17812== by 0x500B22: _ZNSt16allocator_traitsI16secure_allocatorIhEE9constructIhJEEEDTcl12_S_constructfp_fp0_spclsr3stdE7forwardIT0_Efp1_EEERS1_PT_DpOS4_ (alloc_traits.h:344) ==17812== by 0x500982: unsigned char* std::__uninitialized_default_n_a<unsigned char*, unsigned long, secure_allocator<unsigned char> >(unsigned char*, unsigned long, secure_allocator<unsigned char>&) (stl_uninitialized.h:631) ==17812== by 0x60BFC2: std::vector<unsigned char, secure_allocator<unsigned char> >::_M_default_initialize(unsigned long) (stl_vector.h:1347) ==17812== by 0x60BD86: std::vector<unsigned char, secure_allocator<unsigned char> >::vector(unsigned long, secure_allocator<unsigned char> const&) (stl_vector.h:285) ==17812== by 0x60BB55: ECC_Start() (key.cpp:351) ==17812== by 0x16AC90: AppInitSanityChecks() (init.cpp:1162) ==17812== by 0x15BAC9: AppInit(int, char**) (bitcoind.cpp:138) ==17812== by 0x15B6C8: main (bitcoind.cpp:201) ==17812== Address 0x3ffdf is not stack'd, malloc'd or (recently) free'd … Segmentation fault (core dumped) ``` After this patch (with failing `mmap` call): ``` $ src/bitcoind … 2019-01-06T15:50:18Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation 2019-01-06T15:50:18Z Using RdRand as an additional entropy source 2019-01-06T15:50:18Z ************************ EXCEPTION: St9bad_alloc std::bad_alloc bitcoin in AppInit() ************************ EXCEPTION: St9bad_alloc std::bad_alloc bitcoin in AppInit() 2019-01-06T15:50:18Z Shutdown: In progress... 2019-01-06T15:50:18Z Shutdown: done ``` To simulate the failing `mmap` call apply the following to `master`: ```diff diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index 8d577cf..ce79e569b 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -247,7 +247,8 @@ void *PosixLockedPageAllocator::AllocateLocked(size_t len, bool *lockingSuccess) { void *addr; len = align_up(len, page_size); - addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + // addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + addr = MAP_FAILED; if (addr) { *lockingSuccess = mlock(addr, len) == 0; } ``` Tree-SHA512: 66947f5fc0fbb19afb3e1edbd51df07df9d16b77018cff3d48d30f378a53d6a0dc62bc36622b3966b7e374e61edbcca114ef4ac8ae8d725022c1a597edcbf7c7
…(...) in PosixLockedPageAllocator::AllocateLocked ca126d4 Fix out-of-bounds write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked (practicalswift) Pull request description: `mmap(...)` returns `MAP_FAILED` (`(void *) -1`) in case of allocation failure. `PosixLockedPageAllocator::AllocateLocked(...)` did not check for allocation failures prior to this PR. Instead the invalid memory address `(void *) -1` (`0xffffffffffffffff`) was passed to the caller as if it was a valid address. After some operations the address is wrapped around from `0xffffffffffffffff` to `0x00000003ffdf` (`0xffffffffffffffff + 262112 == 0x00000003ffdf`); The resulting address `0x00000003ffdf` is then written to. Before this patch (with failing `mmap` call): ``` $ src/bitcoind … 2019-01-06T16:28:14Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation 2019-01-06T16:28:14Z Using RdRand as an additional entropy source Segmentation fault (core dumped) ``` Before this patch (under `valgrind` with failing `mmap` call): ``` $ valgrind src/bitcoind … 2019-01-06T16:28:51Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation ==17812== Invalid write of size 1 ==17812== at 0x500B7E: void __gnu_cxx::new_allocator<unsigned char>::construct<unsigned char>(unsigned char*) (new_allocator.h:136) ==17812== by 0x500B52: _ZNSt16allocator_traitsI16secure_allocatorIhEE12_S_constructIhJEEENSt9enable_ifIXsr6__and_INS2_18__construct_helperIT_JDpT0_EE4typeEEE5valueEvE4typeERS1_PS6_DpOS7_ (alloc_traits.h:243) ==17812== by 0x500B22: _ZNSt16allocator_traitsI16secure_allocatorIhEE9constructIhJEEEDTcl12_S_constructfp_fp0_spclsr3stdE7forwardIT0_Efp1_EEERS1_PT_DpOS4_ (alloc_traits.h:344) ==17812== by 0x500982: unsigned char* std::__uninitialized_default_n_a<unsigned char*, unsigned long, secure_allocator<unsigned char> >(unsigned char*, unsigned long, secure_allocator<unsigned char>&) (stl_uninitialized.h:631) ==17812== by 0x60BFC2: std::vector<unsigned char, secure_allocator<unsigned char> >::_M_default_initialize(unsigned long) (stl_vector.h:1347) ==17812== by 0x60BD86: std::vector<unsigned char, secure_allocator<unsigned char> >::vector(unsigned long, secure_allocator<unsigned char> const&) (stl_vector.h:285) ==17812== by 0x60BB55: ECC_Start() (key.cpp:351) ==17812== by 0x16AC90: AppInitSanityChecks() (init.cpp:1162) ==17812== by 0x15BAC9: AppInit(int, char**) (bitcoind.cpp:138) ==17812== by 0x15B6C8: main (bitcoind.cpp:201) ==17812== Address 0x3ffdf is not stack'd, malloc'd or (recently) free'd … Segmentation fault (core dumped) ``` After this patch (with failing `mmap` call): ``` $ src/bitcoind … 2019-01-06T15:50:18Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation 2019-01-06T15:50:18Z Using RdRand as an additional entropy source 2019-01-06T15:50:18Z ************************ EXCEPTION: St9bad_alloc std::bad_alloc bitcoin in AppInit() ************************ EXCEPTION: St9bad_alloc std::bad_alloc bitcoin in AppInit() 2019-01-06T15:50:18Z Shutdown: In progress... 2019-01-06T15:50:18Z Shutdown: done ``` To simulate the failing `mmap` call apply the following to `master`: ```diff diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index 8d577cf..ce79e569b 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -247,7 +247,8 @@ void *PosixLockedPageAllocator::AllocateLocked(size_t len, bool *lockingSuccess) { void *addr; len = align_up(len, page_size); - addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + // addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + addr = MAP_FAILED; if (addr) { *lockingSuccess = mlock(addr, len) == 0; } ``` Tree-SHA512: 66947f5fc0fbb19afb3e1edbd51df07df9d16b77018cff3d48d30f378a53d6a0dc62bc36622b3966b7e374e61edbcca114ef4ac8ae8d725022c1a597edcbf7c7
9295568 Fix segfault in allocator_tests/arena_tests (Jeffrey Czyz) f7d88f5 Define ARENA_DEBUG in GA test runs (furszy) cae2e13 Fix compilation errors in support/lockedpool.cpp (Jeffrey Czyz) d19359f fix nits: variable naming, typos (Martin Ankerl) 5cbd967 Use best-fit strategy in Arena, now O(log(n)) instead O(n) (Martin Ankerl) 1ccd62e Fix out-of-bounds write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked (practicalswift) 7ad7157 LockedPool: avoid quadratic-time allocation (Kaz Wesley) 39e1b3b LockedPool: fix explosion for illegal-sized alloc (Kaz Wesley) adb1f1c LockedPool: test handling of invalid allocations (Kaz Wesley) 626b865 Do not shadow variable, use deprecated MAP_ANON if MAP_ANONYMOUS is not defined. (Pavel Janík) Pull request description: Follow up to #2276. Completing the locked memory manager todo list. Back porting: * bitcoin#9063. * bitcoin#9070. * bitcoin#12048. * bitcoin#15117. * bitcoin#16161. ACKs for top commit: random-zebra: ACK 9295568 Fuzzbawls: ACK 9295568 Tree-SHA512: 0d14c7e8231386ee32f1fefac08de9ee278c02d6b0e5172c055851d33c803b0be3398fc5173457e539179712a13d4736033a926f318e576789b4d57b67eb0596
…(...) in PosixLockedPageAllocator::AllocateLocked ca126d4 Fix out-of-bounds write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked (practicalswift) Pull request description: `mmap(...)` returns `MAP_FAILED` (`(void *) -1`) in case of allocation failure. `PosixLockedPageAllocator::AllocateLocked(...)` did not check for allocation failures prior to this PR. Instead the invalid memory address `(void *) -1` (`0xffffffffffffffff`) was passed to the caller as if it was a valid address. After some operations the address is wrapped around from `0xffffffffffffffff` to `0x00000003ffdf` (`0xffffffffffffffff + 262112 == 0x00000003ffdf`); The resulting address `0x00000003ffdf` is then written to. Before this patch (with failing `mmap` call): ``` $ src/bitcoind … 2019-01-06T16:28:14Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation 2019-01-06T16:28:14Z Using RdRand as an additional entropy source Segmentation fault (core dumped) ``` Before this patch (under `valgrind` with failing `mmap` call): ``` $ valgrind src/bitcoind … 2019-01-06T16:28:51Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation ==17812== Invalid write of size 1 ==17812== at 0x500B7E: void __gnu_cxx::new_allocator<unsigned char>::construct<unsigned char>(unsigned char*) (new_allocator.h:136) ==17812== by 0x500B52: _ZNSt16allocator_traitsI16secure_allocatorIhEE12_S_constructIhJEEENSt9enable_ifIXsr6__and_INS2_18__construct_helperIT_JDpT0_EE4typeEEE5valueEvE4typeERS1_PS6_DpOS7_ (alloc_traits.h:243) ==17812== by 0x500B22: _ZNSt16allocator_traitsI16secure_allocatorIhEE9constructIhJEEEDTcl12_S_constructfp_fp0_spclsr3stdE7forwardIT0_Efp1_EEERS1_PT_DpOS4_ (alloc_traits.h:344) ==17812== by 0x500982: unsigned char* std::__uninitialized_default_n_a<unsigned char*, unsigned long, secure_allocator<unsigned char> >(unsigned char*, unsigned long, secure_allocator<unsigned char>&) (stl_uninitialized.h:631) ==17812== by 0x60BFC2: std::vector<unsigned char, secure_allocator<unsigned char> >::_M_default_initialize(unsigned long) (stl_vector.h:1347) ==17812== by 0x60BD86: std::vector<unsigned char, secure_allocator<unsigned char> >::vector(unsigned long, secure_allocator<unsigned char> const&) (stl_vector.h:285) ==17812== by 0x60BB55: ECC_Start() (key.cpp:351) ==17812== by 0x16AC90: AppInitSanityChecks() (init.cpp:1162) ==17812== by 0x15BAC9: AppInit(int, char**) (bitcoind.cpp:138) ==17812== by 0x15B6C8: main (bitcoind.cpp:201) ==17812== Address 0x3ffdf is not stack'd, malloc'd or (recently) free'd … Segmentation fault (core dumped) ``` After this patch (with failing `mmap` call): ``` $ src/bitcoind … 2019-01-06T15:50:18Z Using the 'sse4(1way),sse41(4way)' SHA256 implementation 2019-01-06T15:50:18Z Using RdRand as an additional entropy source 2019-01-06T15:50:18Z ************************ EXCEPTION: St9bad_alloc std::bad_alloc bitcoin in AppInit() ************************ EXCEPTION: St9bad_alloc std::bad_alloc bitcoin in AppInit() 2019-01-06T15:50:18Z Shutdown: In progress... 2019-01-06T15:50:18Z Shutdown: done ``` To simulate the failing `mmap` call apply the following to `master`: ```diff diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index 8d577cf..ce79e569b 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -247,7 +247,8 @@ void *PosixLockedPageAllocator::AllocateLocked(size_t len, bool *lockingSuccess) { void *addr; len = align_up(len, page_size); - addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + // addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + addr = MAP_FAILED; if (addr) { *lockingSuccess = mlock(addr, len) == 0; } ``` Tree-SHA512: 66947f5fc0fbb19afb3e1edbd51df07df9d16b77018cff3d48d30f378a53d6a0dc62bc36622b3966b7e374e61edbcca114ef4ac8ae8d725022c1a597edcbf7c7
mmap(...)
returnsMAP_FAILED
((void *) -1
) in case of allocation failure.PosixLockedPageAllocator::AllocateLocked(...)
did not check for allocation failures prior to this PR.Instead the invalid memory address
(void *) -1
(0xffffffffffffffff
) was passed to the caller as if it was a valid address.After some operations the address is wrapped around from
0xffffffffffffffff
to0x00000003ffdf
(0xffffffffffffffff + 262112 == 0x00000003ffdf
);The resulting address
0x00000003ffdf
is then written to.Before this patch (with failing
mmap
call):Before this patch (under
valgrind
with failingmmap
call):After this patch (with failing
mmap
call):To simulate the failing
mmap
call apply the following tomaster
: