Make *allocx() size class overflow behavior defined.

Limit supported size and alignment to HUGE_MAXCLASS, which in turn is
now limited to be less than PTRDIFF_MAX.

This resolves #278 and #295.
This commit is contained in:
Jason Evans
2016-02-25 15:29:49 -08:00
parent 767d85061a
commit 0c516a00c4
14 changed files with 247 additions and 89 deletions

View File

@@ -46,6 +46,35 @@ get_huge_size(size_t ind)
return (get_size_impl("arenas.hchunk.0.size", ind));
}
TEST_BEGIN(test_overflow)
{
size_t hugemax, size;
hugemax = get_huge_size(get_nhuge()-1);
assert_ptr_null(mallocx(hugemax+1, 0),
"Expected OOM for mallocx(size=%#zx, 0)", hugemax+1);
assert_ptr_null(mallocx(PTRDIFF_MAX+1, 0),
"Expected OOM for mallocx(size=%#zx, 0)", ZU(PTRDIFF_MAX+1));
assert_ptr_null(mallocx(SIZE_T_MAX, 0),
"Expected OOM for mallocx(size=%#zx, 0)", SIZE_T_MAX);
#if LG_SIZEOF_PTR == 3
size = ZU(0x600000000000000);
#else
size = ZU(0x6000000);
#endif
assert_ptr_null(mallocx(size, 0),
"Expected OOM for mallocx(size=%#zx, 0", size);
assert_ptr_null(mallocx(1, MALLOCX_ALIGN(PTRDIFF_MAX+1)),
"Expected OOM for mallocx(size=1, MALLOCX_ALIGN(%#zx))",
ZU(PTRDIFF_MAX+1));
}
TEST_END
TEST_BEGIN(test_oom)
{
size_t hugemax, size, alignment;
@@ -176,6 +205,7 @@ main(void)
{
return (test(
test_overflow,
test_oom,
test_basic,
test_alignment_and_size));

View File

@@ -1,5 +1,51 @@
#include "test/jemalloc_test.h"
static unsigned
get_nsizes_impl(const char *cmd)
{
unsigned ret;
size_t z;
z = sizeof(unsigned);
assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,
"Unexpected mallctl(\"%s\", ...) failure", cmd);
return (ret);
}
static unsigned
get_nhuge(void)
{
return (get_nsizes_impl("arenas.nhchunks"));
}
static size_t
get_size_impl(const char *cmd, size_t ind)
{
size_t ret;
size_t z;
size_t mib[4];
size_t miblen = 4;
z = sizeof(size_t);
assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
mib[2] = ind;
z = sizeof(size_t);
assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),
0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
return (ret);
}
static size_t
get_huge_size(size_t ind)
{
return (get_size_impl("arenas.hchunk.0.size", ind));
}
TEST_BEGIN(test_grow_and_shrink)
{
void *p, *q;
@@ -173,6 +219,41 @@ TEST_BEGIN(test_lg_align_and_zero)
}
TEST_END
TEST_BEGIN(test_overflow)
{
size_t hugemax, size;
void *p;
hugemax = get_huge_size(get_nhuge()-1);
p = mallocx(1, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_ptr_null(rallocx(p, hugemax+1, 0),
"Expected OOM for rallocx(p, size=%#zx, 0)", hugemax+1);
assert_ptr_null(rallocx(p, PTRDIFF_MAX+1, 0),
"Expected OOM for rallocx(p, size=%#zx, 0)", ZU(PTRDIFF_MAX+1));
assert_ptr_null(rallocx(p, SIZE_T_MAX, 0),
"Expected OOM for rallocx(p, size=%#zx, 0)", SIZE_T_MAX);
#if LG_SIZEOF_PTR == 3
size = ZU(0x600000000000000);
#else
size = ZU(0x6000000);
#endif
assert_ptr_null(rallocx(p, size, 0),
"Expected OOM for rallocx(p, size=%#zx, 0", size);
assert_ptr_null(rallocx(p, 1, MALLOCX_ALIGN(PTRDIFF_MAX+1)),
"Expected OOM for rallocx(p, size=1, MALLOCX_ALIGN(%#zx))",
ZU(PTRDIFF_MAX+1));
dallocx(p, 0);
}
TEST_END
int
main(void)
{
@@ -181,5 +262,6 @@ main(void)
test_grow_and_shrink,
test_zero,
test_align,
test_lg_align_and_zero));
test_lg_align_and_zero,
test_overflow));
}

View File

@@ -80,10 +80,33 @@ TEST_BEGIN(test_size_classes)
}
TEST_END
TEST_BEGIN(test_overflow)
{
size_t max_size_class;
max_size_class = get_max_size_class();
assert_u_ge(size2index(max_size_class+1), NSIZES,
"size2index() should return >= NSIZES on overflow");
assert_u_ge(size2index(PTRDIFF_MAX+1), NSIZES,
"size2index() should return >= NSIZES on overflow");
assert_u_ge(size2index(SIZE_T_MAX), NSIZES,
"size2index() should return >= NSIZES on overflow");
assert_zu_gt(s2u(max_size_class+1), HUGE_MAXCLASS,
"s2u() should return > HUGE_MAXCLASS for unsupported size");
assert_zu_gt(s2u(PTRDIFF_MAX+1), HUGE_MAXCLASS,
"s2u() should return > HUGE_MAXCLASS for unsupported size");
assert_zu_eq(s2u(SIZE_T_MAX), 0,
"s2u() should return 0 on overflow");
}
TEST_END
int
main(void)
{
return (test(
test_size_classes));
test_size_classes,
test_overflow));
}