[glibc] Add system-wide tunables: implement overridability
DJ Delorie via Glibc-cvs <[email protected]> Thu, 9 Jul 2026 01:59:05 +0000 (GMT)
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=617376a04b28efe0e17c9227557ef6231735b0eb commit 617376a04b28efe0e17c9227557ef6231735b0eb Author: DJ Delorie <[email protected]> Date: Mon Jul 6 23:27:44 2026 -0400 Add system-wide tunables: implement overridability Implement the overridability/nonoverridability flags for tunables. Reviewed-by: Adhemerval Zanella <[email protected]> Diff: --- elf/Makefile | 6 +++++- elf/dl-tunable-types.h | 2 ++ elf/dl-tunables.c | 15 +++++++++++++++ elf/tst-tunconf1.c | 20 ++++++++++++++++++++ elf/tst-tunconf1.root/etc/tunables.conf | 8 ++++++++ elf/tunconf.c | 26 ++++++++++++++++---------- scripts/gen-tunables.awk | 2 +- 7 files changed, 67 insertions(+), 12 deletions(-) diff --git a/elf/Makefile b/elf/Makefile index e7b624ec57..01e77f2ca0 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -347,7 +347,11 @@ tests-static += \ tst-tls9-static \ # tests-static -tst-tunconf1-TUNABLES-only = glibc.malloc.tcache_count=5 +tst-tunconf1-TUNABLES-only = \ + glibc.malloc.tcache_count=5 \ + glibc.malloc.perturb=41 \ + glibc.malloc.mmap_threshold=10002 \ + glibc.malloc.trim_threshold=10002 static-dlopen-environment = \ LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx)dlfcn diff --git a/elf/dl-tunable-types.h b/elf/dl-tunable-types.h index f421c01c26..3506eee512 100644 --- a/elf/dl-tunable-types.h +++ b/elf/dl-tunable-types.h @@ -65,6 +65,8 @@ struct _tunable tunable_val_t val; /* The value. */ bool initialized; /* Flag to indicate that the tunable is initialized. */ + bool locked; /* If set, modifications are not + allowed. */ /* Compatibility elements. */ const char env_alias[TUNABLE_ALIAS_MAX]; /* The compatibility environment variable name. */ diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c index 197d940d38..d19c2358c1 100644 --- a/elf/dl-tunables.c +++ b/elf/dl-tunables.c @@ -72,6 +72,9 @@ do_tunable_update_val (tunable_t *cur, const tunable_val_t *valp, { tunable_num_t val, min, max; + if (cur->locked) + return; + switch (cur->type.type_code) { case TUNABLE_TYPE_STRING: @@ -409,6 +412,12 @@ __tunables_init (char **envp, char **argv) goto skip_due_to_filter; } + /* If the tunable is set here, any previously set + overridability flag is discarded. We need to reset the + overridability flag here so we can change the tunable, + and may set it later if this tunable also locks it. */ + tunable_list[tid].locked = false; + /* See if the parsed type matches the desired type. */ if (tunable_list[tid].type.type_code == TUNABLE_TYPE_STRING) { @@ -435,6 +444,12 @@ __tunables_init (char **envp, char **argv) } } + /* The overriability flag only applies to tunables + which aren't filtered out. */ + if ((tec->flags & TUNCONF_FLAG_OVERRIDABLE) + == TUNCONF_OVERRIDE_DENY) + tunable_list[tid].locked = true; + skip_due_to_filter:; } } diff --git a/elf/tst-tunconf1.c b/elf/tst-tunconf1.c index c95a7cb8ba..74f596d913 100644 --- a/elf/tst-tunconf1.c +++ b/elf/tst-tunconf1.c @@ -26,10 +26,30 @@ do_test (void) { size_t tcache_count = TUNABLE_GET_FULL (glibc, malloc, tcache_count, size_t, NULL); size_t tcache_max = TUNABLE_GET_FULL (glibc, malloc, tcache_max, size_t, NULL); + size_t perturb = TUNABLE_GET_FULL (glibc, malloc, perturb, size_t, NULL); + size_t mmap_threshold = TUNABLE_GET_FULL (glibc, malloc, mmap_threshold, size_t, NULL); + size_t trim_threshold = TUNABLE_GET_FULL (glibc, malloc, trim_threshold, size_t, NULL); + printf("tcache count is %ld (should be 5, from env)\n", (long)tcache_count); TEST_COMPARE ((long)tcache_count, 5); printf("tcache max is %ld (should be 4, from /etc)\n", (long)tcache_max); TEST_COMPARE ((long)tcache_max, 4); + + /* This is set by the environment but blocked by the config. */ + printf("perturb is %ld (should be 42, from /etc)\n", + (long)perturb); + TEST_COMPARE ((long)perturb, 42); + + /* This is blocked by the general config, enabled by filter, set in env. */ + printf("mmap_threshold is %ld (should be 10002, from env)\n", + (long)mmap_threshold); + TEST_COMPARE ((long)mmap_threshold, 10002); + + /* This is allowed by the general config, blocked by filter, set in env. */ + printf("trim_threshold is %ld (should be 10001, from filter)\n", + (long)trim_threshold); + TEST_COMPARE ((long)trim_threshold, 10001); + return 0; } diff --git a/elf/tst-tunconf1.root/etc/tunables.conf b/elf/tst-tunconf1.root/etc/tunables.conf index f373a67902..f708a8fce4 100644 --- a/elf/tst-tunconf1.root/etc/tunables.conf +++ b/elf/tst-tunconf1.root/etc/tunables.conf @@ -8,7 +8,15 @@ $glibc.test_unsecure=1 # These are checked inside the test case glibc.malloc.tcache_max=6 $glibc.malloc.tcache_count=3 + +-glibc.malloc.perturb=42 +-glibc.malloc.mmap_threshold=10000 +overridable glibc.malloc.trim_threshold=10000 + [proc:/bin/ls] glibc.malloc.tcache_max=7 + [proc:tst-tunconf1] glibc.malloc.tcache_max=4 ++glibc.malloc.mmap_threshold=10001 +nonoverridable glibc.malloc.trim_threshold=10001 diff --git a/elf/tunconf.c b/elf/tunconf.c index a5ca755abd..c27b50b1de 100644 --- a/elf/tunconf.c +++ b/elf/tunconf.c @@ -194,34 +194,40 @@ add_tunable (char *line, const char *filename, int lineno) /* Parse modifiers. */ while (*line) { - if (strncmp (line, "overridable ", 13) == 0) + int prefix_len; + +#define TUN_PREFIX(s) \ + prefix_len = sizeof(s) - 1, \ + strncmp (line, s " ", prefix_len + 1) == 0 + + if (TUN_PREFIX("overridable")) { top = TOP_ALLOW; /* The line++ below skips the space. */ - line += 12; + line += prefix_len; } - else if (strncmp (line, "nonoverridable ", 16) == 0) + else if (TUN_PREFIX ("nonoverridable")) { top = TOP_DENY; - line += 15; + line += prefix_len; } - else if (strncmp (line, "onlysecure ", 11) == 0) + else if (TUN_PREFIX ("onlysecure")) { exclude_nonsecure = 1; exclude_secure = 0; - line += 10; + line += prefix_len; } - else if (strncmp (line, "nonsecure ", 10) == 0) + else if (TUN_PREFIX ("nonsecure")) { exclude_secure = 1; exclude_nonsecure = 0; - line += 9; + line += prefix_len; } - else if (strncmp (line, "anysecure ", 10) == 0) + else if (TUN_PREFIX ("anysecure")) { exclude_secure = 0; exclude_nonsecure = 0; - line += 9; + line += prefix_len; } else switch (*line) { diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk index 5d34075c16..7c832303db 100644 --- a/scripts/gen-tunables.awk +++ b/scripts/gen-tunables.awk @@ -169,7 +169,7 @@ END { n = indices[2]; m = indices[3]; printf (" {TUNABLE_NAME_S(%s, %s, %s)", t, n, m) - printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, {%s}, false, %s},\n", + printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, {%s}, false, false, %s},\n", types[t,n,m], minvals[t,n,m], maxvals[t,n,m], default_val[t,n,m], default_val[t,n,m], env_alias[t,n,m]); }