1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-08 17:42:12 +03:00

elf: Ignore GLIBC_TUNABLES for setuid/setgid binaries

The tunable privilege levels were a retrofit to try and keep the malloc
tunable environment variables' behavior unchanged across security
boundaries.  However, CVE-2023-4911 shows how tricky can be
tunable parsing in a security-sensitive environment.

Not only parsing, but the malloc tunable essentially changes some
semantics on setuid/setgid processes.  Although it is not a direct
security issue, allowing users to change setuid/setgid semantics is not
a good security practice, and requires extra code and analysis to check
if each tunable is safe to use on all security boundaries.

It also means that security opt-in features, like aarch64 MTE, would
need to be explicit enabled by an administrator with a wrapper script
or with a possible future system-wide tunable setting.

Co-authored-by: Siddhesh Poyarekar  <siddhesh@sourceware.org>
Reviewed-by: DJ Delorie <dj@redhat.com>
This commit is contained in:
Adhemerval Zanella
2023-11-06 17:25:36 -03:00
parent a72a4eb10b
commit 9c96c87d60
9 changed files with 299 additions and 161 deletions

View File

@@ -15,14 +15,10 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* Verify that tunables correctly filter out unsafe tunables like
glibc.malloc.check and glibc.malloc.mmap_threshold but also retain
glibc.malloc.mmap_threshold in an unprivileged child. */
#define _LIBC 1
#include "config.h"
#undef _LIBC
/* Verify that GLIBC_TUNABLES is kept unchanged but no tunable is actually
enabled for AT_SECURE processes. */
#include <dl-tunables.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -40,7 +36,7 @@
#include <support/test-driver.h>
#include <support/capture_subprocess.h>
const char *teststrings[] =
static const char *teststrings[] =
{
"glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
"glibc.malloc.check=2:glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
@@ -74,6 +70,23 @@ test_child (int off)
ret = 0;
fflush (stdout);
/* Also check if the set tunables are effectively unchanged. */
int32_t check = TUNABLE_GET_FULL (glibc, malloc, check, int32_t, NULL);
size_t mmap_threshold = TUNABLE_GET_FULL (glibc, malloc, mmap_threshold,
size_t, NULL);
int32_t perturb = TUNABLE_GET_FULL (glibc, malloc, perturb, int32_t, NULL);
printf (" [%d] glibc.malloc.check=%d\n", off, check);
fflush (stdout);
printf (" [%d] glibc.malloc.mmap_threshold=%zu\n", off, mmap_threshold);
fflush (stdout);
printf (" [%d] glibc.malloc.perturb=%d\n", off, perturb);
fflush (stdout);
ret |= check != 0;
ret |= mmap_threshold != 0;
ret |= perturb != 0;
return ret;
}