Rename zero_realloc option "strict" to "alloc".
With realloc(ptr, 0) being UB per C23, the option name "strict" makes less sense now. Rename to "alloc" which describes the behavior.
This commit is contained in:
parent
5841b6dbe7
commit
0e29ad4efa
@ -289,7 +289,7 @@ TESTS_UNIT := \
|
|||||||
$(srcroot)test/unit/zero.c \
|
$(srcroot)test/unit/zero.c \
|
||||||
$(srcroot)test/unit/zero_realloc_abort.c \
|
$(srcroot)test/unit/zero_realloc_abort.c \
|
||||||
$(srcroot)test/unit/zero_realloc_free.c \
|
$(srcroot)test/unit/zero_realloc_free.c \
|
||||||
$(srcroot)test/unit/zero_realloc_strict.c \
|
$(srcroot)test/unit/zero_realloc_alloc.c \
|
||||||
$(srcroot)test/unit/zero_reallocs.c
|
$(srcroot)test/unit/zero_reallocs.c
|
||||||
ifeq (@enable_prof@, 1)
|
ifeq (@enable_prof@, 1)
|
||||||
TESTS_UNIT += \
|
TESTS_UNIT += \
|
||||||
|
@ -1580,19 +1580,19 @@ malloc_conf = "xmalloc:true";]]></programlisting>
|
|||||||
</term>
|
</term>
|
||||||
<listitem><para> Determines the behavior of
|
<listitem><para> Determines the behavior of
|
||||||
<function>realloc()</function> when passed a value of zero for the new
|
<function>realloc()</function> when passed a value of zero for the new
|
||||||
size. <quote>strict</quote> treats this as an allocation of size zero
|
size. <quote>alloc</quote> treats this as an allocation of size zero
|
||||||
(and returns a non-null result except in case of resource exhaustion).
|
(and returns a non-null result except in case of resource exhaustion).
|
||||||
<quote>free</quote> treats this as a deallocation of the pointer, and
|
<quote>free</quote> treats this as a deallocation of the pointer, and
|
||||||
returns <constant>NULL</constant> without setting
|
returns <constant>NULL</constant> without setting
|
||||||
<varname>errno</varname>. <quote>abort</quote> aborts the process if
|
<varname>errno</varname>. <quote>abort</quote> aborts the process if
|
||||||
zero is passed. The default is <quote>strict</quote>.</para>
|
zero is passed. The default is <quote>alloc</quote>.</para>
|
||||||
|
|
||||||
<para>There is considerable divergence of behaviors across
|
<para>There is considerable divergence of behaviors across
|
||||||
implementations in handling this case. Many have the behavior of
|
implementations in handling this case. Many have the behavior of
|
||||||
<quote>free</quote>. This can introduce security vulnerabilities, since
|
<quote>free</quote>. This can introduce security vulnerabilities, since
|
||||||
a <constant>NULL</constant> return value indicates failure, and the
|
a <constant>NULL</constant> return value indicates failure, and the
|
||||||
continued validity of the passed-in pointer (per POSIX and C11).
|
continued validity of the passed-in pointer (per POSIX and C11).
|
||||||
<quote>strict</quote> is safe, but can cause leaks in programs that
|
<quote>alloc</quote> is safe, but can cause leaks in programs that
|
||||||
expect the common behavior. Programs intended to be portable and
|
expect the common behavior. Programs intended to be portable and
|
||||||
leak-free cannot assume either behavior, and must therefore never call
|
leak-free cannot assume either behavior, and must therefore never call
|
||||||
realloc with a size of 0. The <quote>abort</quote> option enables these
|
realloc with a size of 0. The <quote>abort</quote> option enables these
|
||||||
|
@ -9,7 +9,7 @@ typedef int malloc_cpuid_t;
|
|||||||
/* When realloc(non-null-ptr, 0) is called, what happens? */
|
/* When realloc(non-null-ptr, 0) is called, what happens? */
|
||||||
enum zero_realloc_action_e {
|
enum zero_realloc_action_e {
|
||||||
/* Realloc(ptr, 0) is free(ptr); return malloc(0); */
|
/* Realloc(ptr, 0) is free(ptr); return malloc(0); */
|
||||||
zero_realloc_action_strict = 0,
|
zero_realloc_action_alloc = 0,
|
||||||
/* Realloc(ptr, 0) is free(ptr); */
|
/* Realloc(ptr, 0) is free(ptr); */
|
||||||
zero_realloc_action_free = 1,
|
zero_realloc_action_free = 1,
|
||||||
/* Realloc(ptr, 0) aborts. */
|
/* Realloc(ptr, 0) aborts. */
|
||||||
|
@ -112,12 +112,12 @@ bool opt_cache_oblivious =
|
|||||||
;
|
;
|
||||||
|
|
||||||
zero_realloc_action_t opt_zero_realloc_action =
|
zero_realloc_action_t opt_zero_realloc_action =
|
||||||
zero_realloc_action_strict;
|
zero_realloc_action_alloc;
|
||||||
|
|
||||||
atomic_zu_t zero_realloc_count = ATOMIC_INIT(0);
|
atomic_zu_t zero_realloc_count = ATOMIC_INIT(0);
|
||||||
|
|
||||||
const char *zero_realloc_mode_names[] = {
|
const char *zero_realloc_mode_names[] = {
|
||||||
"strict",
|
"alloc",
|
||||||
"free",
|
"free",
|
||||||
"abort",
|
"abort",
|
||||||
};
|
};
|
||||||
@ -1649,9 +1649,9 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
|
|||||||
CONF_CONTINUE;
|
CONF_CONTINUE;
|
||||||
}
|
}
|
||||||
if (CONF_MATCH("zero_realloc")) {
|
if (CONF_MATCH("zero_realloc")) {
|
||||||
if (CONF_MATCH_VALUE("strict")) {
|
if (CONF_MATCH_VALUE("alloc")) {
|
||||||
opt_zero_realloc_action
|
opt_zero_realloc_action
|
||||||
= zero_realloc_action_strict;
|
= zero_realloc_action_alloc;
|
||||||
} else if (CONF_MATCH_VALUE("free")) {
|
} else if (CONF_MATCH_VALUE("free")) {
|
||||||
opt_zero_realloc_action
|
opt_zero_realloc_action
|
||||||
= zero_realloc_action_free;
|
= zero_realloc_action_free;
|
||||||
@ -3578,9 +3578,9 @@ do_realloc_nonnull_zero(void *ptr) {
|
|||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
atomic_fetch_add_zu(&zero_realloc_count, 1, ATOMIC_RELAXED);
|
atomic_fetch_add_zu(&zero_realloc_count, 1, ATOMIC_RELAXED);
|
||||||
}
|
}
|
||||||
if (opt_zero_realloc_action == zero_realloc_action_strict) {
|
if (opt_zero_realloc_action == zero_realloc_action_alloc) {
|
||||||
/*
|
/*
|
||||||
* The user might have gotten a strict setting while expecting a
|
* The user might have gotten an alloc setting while expecting a
|
||||||
* free setting. If that's the case, we at least try to
|
* free setting. If that's the case, we at least try to
|
||||||
* reduce the harm, and turn off the tcache while allocating, so
|
* reduce the harm, and turn off the tcache while allocating, so
|
||||||
* that we'll get a true first fit.
|
* that we'll get a true first fit.
|
||||||
|
@ -24,7 +24,7 @@ deallocated() {
|
|||||||
return deallocated;
|
return deallocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_BEGIN(test_realloc_strict) {
|
TEST_BEGIN(test_realloc_alloc) {
|
||||||
void *ptr = mallocx(1, 0);
|
void *ptr = mallocx(1, 0);
|
||||||
expect_ptr_not_null(ptr, "Unexpected mallocx error");
|
expect_ptr_not_null(ptr, "Unexpected mallocx error");
|
||||||
uint64_t allocated_before = allocated();
|
uint64_t allocated_before = allocated();
|
||||||
@ -44,5 +44,5 @@ TEST_END
|
|||||||
int
|
int
|
||||||
main(void) {
|
main(void) {
|
||||||
return test(
|
return test(
|
||||||
test_realloc_strict);
|
test_realloc_alloc);
|
||||||
}
|
}
|
3
test/unit/zero_realloc_alloc.sh
Normal file
3
test/unit/zero_realloc_alloc.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export MALLOC_CONF="zero_realloc:alloc"
|
@ -1,3 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export MALLOC_CONF="zero_realloc:strict"
|
|
Loading…
Reference in New Issue
Block a user