Skip to content

Commit cf121df

Browse files
committed
8295889: NMT preinit code does not handle allocation errors
Reviewed-by: dholmes, mbaesken
1 parent 772be2e commit cf121df

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/hotspot/share/services/nmtPreInit.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,22 @@ static void raw_free(void* p) { ALLOW_C_FUNCTION(::free, ::fre
4141
static const size_t malloc_alignment = 2 * sizeof(void*); // could we use max_align_t?
4242
STATIC_ASSERT(is_aligned(sizeof(NMTPreInitAllocation), malloc_alignment));
4343

44+
// To keep matters simple we just raise a fatal error on OOM. Since preinit allocation
45+
// is just used for pre-VM-initialization mallocs, none of which are optional, we don't
46+
// need a finer grained error handling.
47+
static void fail_oom(size_t size) {
48+
vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "VM early initialization phase");
49+
}
50+
4451
// --------- NMTPreInitAllocation --------------
4552

4653
NMTPreInitAllocation* NMTPreInitAllocation::do_alloc(size_t payload_size) {
4754
const size_t outer_size = sizeof(NMTPreInitAllocation) + payload_size;
55+
guarantee(outer_size > payload_size, "Overflow");
4856
void* p = raw_malloc(outer_size);
57+
if (p == nullptr) {
58+
fail_oom(outer_size);
59+
}
4960
NMTPreInitAllocation* a = new(p) NMTPreInitAllocation(payload_size);
5061
return a;
5162
}
@@ -54,7 +65,11 @@ NMTPreInitAllocation* NMTPreInitAllocation::do_reallocate(NMTPreInitAllocation*
5465
assert(old->next == NULL, "unhang from map first");
5566
// We just reallocate the old block, header and all.
5667
const size_t new_outer_size = sizeof(NMTPreInitAllocation) + new_payload_size;
68+
guarantee(new_outer_size > new_payload_size, "Overflow");
5769
void* p = raw_realloc(old, new_outer_size);
70+
if (p == nullptr) {
71+
fail_oom(new_outer_size);
72+
}
5873
// re-stamp header with new size
5974
NMTPreInitAllocation* a = new(p) NMTPreInitAllocation(new_payload_size);
6075
return a;

test/hotspot/gtest/nmt/test_nmtpreinit.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,25 @@ class TestAllocations {
9090
os::free(NULL); // free(null)
9191
DEBUG_ONLY(NMTPreInit::verify();)
9292

93+
// This should result in a fatal native oom error from NMT preinit with a clear error message.
94+
// It should not result in a SEGV or anything similar. Unfortunately difficult to test
95+
// automatically.
96+
// Uncomment to test manually.
97+
98+
// case 1: overflow
99+
// os_malloc(SIZE_MAX);
100+
101+
// case 2: failing malloc
102+
// os_malloc(SIZE_MAX - M);
103+
104+
// case 3: overflow in realloc
105+
// void* p = os_malloc(10);
106+
// p = os_realloc(p, SIZE_MAX);
107+
108+
// case 4: failing realloc
109+
// void* p = os_malloc(10);
110+
// p = os_realloc(p, SIZE_MAX - M);
111+
93112
log_state();
94113
}
95114
void test_post() {

0 commit comments

Comments
 (0)