Skip to content

mrs: make quarantine overhead tunable #2376

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

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 77 additions & 19 deletions lib/libc/stdlib/malloc/mrs/mrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,21 @@
*
* Values:
*
* QUARANTINE_HIGHWATER: Limit the quarantine size to
* QUARANTINE_HIGHWATER number of bytes.
* QUARANTINE_RATIO: Limit the quarantine size to 1 / QUARANTINE_RATIO
* times the size of the heap (default 4).
* CONCURRENT_REVOCATION_PASSES: Number of concurrent revocation pass
* before the stop-the-world pass.
* QUARANTINE_NUMERATOR / QUARANTINE_DENOMINATOR: Limit the quarantine
* size to QUARANTINE_NUMERATOR / QUARANTINE_DENOMINATOR times the size
* of the heap (default 1/4).
*/

#ifdef QUARANTINE_RATIO
#error QUARANTINE_RATIO is obsolete, use QUARANTINE_NUMERATOR/QUARANTINE_DENOMINATOR

Check warning on line 100 in lib/libc/stdlib/malloc/mrs/mrs.c

View workflow job for this annotation

GitHub Actions / Style Checker

line over 80 characters
#endif
#ifndef QUARANTINE_DENOMINATOR
#define QUARANTINE_DENOMINATOR 4
#endif
#ifndef QUARANTINE_NUMERATOR
#define QUARANTINE_NUMERATOR 1
#endif

#define MALLOCX_LG_ALIGN_BITS 6
#define MALLOCX_LG_ALIGN_MASK ((1 << MALLOCX_LG_ALIGN_BITS) - 1)
/* Use MALLOCX_ALIGN_GET() if alignment may not be specified in flags. */
Expand Down Expand Up @@ -132,6 +139,11 @@
#define MALLOC_NOBOUND_CHERI_POINTERS \
"_RUNTIME_NOBOUND_CHERI_POINTERS"

#define MALLOC_QUARANTINE_DENOMINATOR_ENV \
"_RUNTIME_QUARANTINE_DENOMINATOR"
#define MALLOC_QUARANTINE_NUMERATOR_ENV \
"_RUNTIME_QUARANTINE_NUMERATOR"

/*
* Different allocators give their strong symbols different names. Hide
* this implementation detail being the REAL() macro.
Expand Down Expand Up @@ -307,6 +319,9 @@
static bool abort_on_validation_failure = true;
static bool mrs_initialized = false;

static unsigned int quarantine_denominator = QUARANTINE_DENOMINATOR;
static unsigned int quarantine_numerator = QUARANTINE_NUMERATOR;

static spinlock_t mrs_init_lock = _SPINLOCK_INITIALIZER;
#define MRS_LOCK(x) __extension__ ({ \
if (__isthreaded) \
Expand Down Expand Up @@ -757,20 +772,19 @@
return false;
#endif

#if defined(QUARANTINE_HIGHWATER)

return (quarantine->size >= QUARANTINE_HIGHWATER);

#else /* QUARANTINE_HIGHWATER */

#if !defined(QUARANTINE_RATIO)
# define QUARANTINE_RATIO 4
#endif /* !QUARANTINE_RATIO */

return ((allocated_size >= MIN_REVOKE_HEAP_SIZE) &&
((quarantine->size * QUARANTINE_RATIO) >= allocated_size));
if (allocated_size < MIN_REVOKE_HEAP_SIZE)
return false;

Check failure on line 776 in lib/libc/stdlib/malloc/mrs/mrs.c

View workflow job for this annotation

GitHub Actions / Style Checker

parentheses required on return

#endif /* !QUARANTINE_HIGHWATER */
/*
* Flush quarantine if
* quarantine_numerator
* quarantine->size >= allocated_size * ----------------------
* quarantine_denominator
*
* Avoid division by multiplying both sides by quarantine_numerator.
*/
return (quarantine->size * quarantine_denominator >=
allocated_size * quarantine_numerator);
}

static void
Expand Down Expand Up @@ -1307,9 +1321,53 @@
exit(7);
}

char *envstr, *end;
if ((envstr = secure_getenv(MALLOC_QUARANTINE_DENOMINATOR_ENV)) !=
NULL) {
errno = 0;
quarantine_denominator = strtoul(envstr, &end, 0);
if (*end != '\0' ||
(quarantine_denominator == ULONG_MAX &&
errno == ERANGE)) {
mrs_puts("invalid "
MALLOC_QUARANTINE_DENOMINATOR_ENV "\n");
exit(7);
}
}
if ((envstr = secure_getenv(MALLOC_QUARANTINE_NUMERATOR_ENV)) !=
NULL) {
errno = 0;
quarantine_numerator = strtoul(envstr, &end, 0);
if (*end != '\0' ||
(quarantine_numerator == ULONG_MAX &&
errno == ERANGE)) {
mrs_puts("invalid "
MALLOC_QUARANTINE_NUMERATOR_ENV "\n");
exit(7);
}
}
if (quarantine_denominator == 0) {
mrs_puts("quarantine_denominator can not be 0\n");
exit(7);
}
if (quarantine_denominator > 256) {
/* Could overflow with 56-bits of userspace addresses */
mrs_puts("quarantine_denominator > 256\n");
exit(7);
}
if (quarantine_numerator == 0) {
mrs_puts("quarantine_numerator can not be 0\n");
exit(7);
}
if (quarantine_numerator > 256) {
/* Could overflow with 56-bits of userspace addresses */
mrs_puts("quarantine_numerator > 256\n");
exit(7);
}

if (!issetugid()) {
mrs_utrace = (getenv(MRS_UTRACE_ENV) != NULL);
}

Check warning on line 1370 in lib/libc/stdlib/malloc/mrs/mrs.c

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line

uint32_t bsdflags;

Expand Down
Loading