This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch siddhesh/tunables updated. glibc-2.21-337-g1d4bf14
- From: siddhesh at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 15 May 2015 12:53:19 -0000
- Subject: GNU C Library master sources branch siddhesh/tunables updated. glibc-2.21-337-g1d4bf14
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, siddhesh/tunables has been updated
via 1d4bf140a7bab33a3b499a92451754d047af7942 (commit)
from ef55017fc03722419146c42ff6cda9f21d3e5644 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1d4bf140a7bab33a3b499a92451754d047af7942
commit 1d4bf140a7bab33a3b499a92451754d047af7942
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Fri May 15 18:19:14 2015 +0530
Add malloc env vars to tunables
Fix up everything in tunables along the way
diff --git a/malloc/arena.c b/malloc/arena.c
index 5259b74..88ff026 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -20,6 +20,7 @@
#include <stdbool.h>
#define TUNABLE_NAMESPACE MALLOC
+#include <tunables/tunables.h>
/* Compile-time constants. */
@@ -307,53 +308,72 @@ ptmalloc_unlock_all2 (void)
# endif
#endif /* !NO_THREADS */
-/* Initialization routine. */
-#include <string.h>
-extern char **_environ;
-static char *
-internal_function
-next_env_entry (char ***position)
+#ifdef SHARED
+static void *
+__failing_morecore (ptrdiff_t d)
{
- char **current = *position;
- char *result = NULL;
+ return (void *) MORECORE_FAILURE;
+}
- while (*current != NULL)
- {
- if (__builtin_expect ((*current)[0] == 'M', 0)
- && (*current)[1] == 'A'
- && (*current)[2] == 'L'
- && (*current)[3] == 'L'
- && (*current)[4] == 'O'
- && (*current)[5] == 'C'
- && (*current)[6] == '_')
- {
- result = &(*current)[7];
+extern struct dl_open_hook *_dl_open_hook;
+libc_hidden_proto (_dl_open_hook);
+#endif
- /* Save current position for next visit. */
- *position = ++current;
+static void
+tunable_set_mallopt_top_pad (const char *val)
+{
+ __libc_mallopt (M_TOP_PAD, atoi (val));
+}
- break;
- }
+static void
+tunable_set_mallopt_perturb (const char *val)
+{
+ __libc_mallopt (M_PERTURB, atoi (val));
+}
- ++current;
- }
+static void
+tunable_set_mallopt_mmap_max (const char *val)
+{
+ __libc_mallopt (M_MMAP_MAX, atoi (val));
+}
- return result;
+static void
+tunable_set_mallopt_arena_max (const char *val)
+{
+ __libc_mallopt (M_ARENA_MAX, atoi (val));
}
+static void
+tunable_set_mallopt_arena_test (const char *val)
+{
+ __libc_mallopt (M_ARENA_TEST, atoi (val));
+}
-#ifdef SHARED
-static void *
-__failing_morecore (ptrdiff_t d)
+static void
+tunable_set_mallopt_trim_threshold (const char *val)
{
- return (void *) MORECORE_FAILURE;
+ __libc_mallopt (M_TRIM_THRESHOLD, atoi (val));
}
-extern struct dl_open_hook *_dl_open_hook;
-libc_hidden_proto (_dl_open_hook);
-#endif
+static void
+tunable_set_mallopt_mmap_threshold (const char *val)
+{
+ __libc_mallopt (M_MMAP_THRESHOLD, atoi (val));
+}
+
+static void
+tunable_set_mallopt_check (const char *val)
+{
+ if (val[0])
+ {
+ __libc_mallopt (M_CHECK_ACTION, (int) (val[0] - '0'));
+ if (check_action != 0)
+ __malloc_check_init ();
+ }
+}
+/* Initialization routine. */
static void
ptmalloc_init (void)
{
@@ -377,74 +397,22 @@ ptmalloc_init (void)
tsd_key_create (&arena_key, NULL);
tsd_setspecific (arena_key, (void *) &main_arena);
thread_atfork (ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2);
- const char *s = NULL;
- if (__glibc_likely (_environ != NULL))
- {
- char **runp = _environ;
- char *envline;
- while (__builtin_expect ((envline = next_env_entry (&runp)) != NULL,
- 0))
- {
- size_t len = strcspn (envline, "=");
+ TUNABLES_NAMESPACE_BEGIN (8);
- if (envline[len] != '=')
- /* This is a "MALLOC_" variable at the end of the string
- without a '=' character. Ignore it since otherwise we
- will access invalid memory below. */
- continue;
+ TUNABLE_REGISTER_SECURE (CHECK, "MALLOC_CHECK_", tunable_set_mallopt_check);
+ TUNABLE_REGISTER (TOP_PAD, "MALLOC_TOP_PAD_", tunable_set_mallopt_top_pad);
+ TUNABLE_REGISTER (PERTURB, "MALLOC_PERTURB_", tunable_set_mallopt_perturb);
+ TUNABLE_REGISTER (MMAP_THRESHOLD, "MALLOC_MMAP_THRESHOLD_",
+ tunable_set_mallopt_mmap_threshold);
+ TUNABLE_REGISTER (TRIM_THRESHOLD, "MALLOC_TRIM_THRESHOLD_",
+ tunable_set_mallopt_trim_threshold);
+ TUNABLE_REGISTER (MMAP_MAX, "MALLOC_MMAP_MAX_", tunable_set_mallopt_mmap_max);
+ TUNABLE_REGISTER (ARENA_MAX, "MALLOC_ARENA_MAX", tunable_set_mallopt_arena_max);
+ TUNABLE_REGISTER (ARENA_TEST, "MALLOC_ARENA_TEST", tunable_set_mallopt_arena_test);
+
+ TUNABLES_NAMESPACE_INIT ();
- switch (len)
- {
- case 6:
- if (memcmp (envline, "CHECK_", 6) == 0)
- s = &envline[7];
- break;
- case 8:
- if (!__builtin_expect (__libc_enable_secure, 0))
- {
- if (memcmp (envline, "TOP_PAD_", 8) == 0)
- __libc_mallopt (M_TOP_PAD, atoi (&envline[9]));
- else if (memcmp (envline, "PERTURB_", 8) == 0)
- __libc_mallopt (M_PERTURB, atoi (&envline[9]));
- }
- break;
- case 9:
- if (!__builtin_expect (__libc_enable_secure, 0))
- {
- if (memcmp (envline, "MMAP_MAX_", 9) == 0)
- __libc_mallopt (M_MMAP_MAX, atoi (&envline[10]));
- else if (memcmp (envline, "ARENA_MAX", 9) == 0)
- __libc_mallopt (M_ARENA_MAX, atoi (&envline[10]));
- }
- break;
- case 10:
- if (!__builtin_expect (__libc_enable_secure, 0))
- {
- if (memcmp (envline, "ARENA_TEST", 10) == 0)
- __libc_mallopt (M_ARENA_TEST, atoi (&envline[11]));
- }
- break;
- case 15:
- if (!__builtin_expect (__libc_enable_secure, 0))
- {
- if (memcmp (envline, "TRIM_THRESHOLD_", 15) == 0)
- __libc_mallopt (M_TRIM_THRESHOLD, atoi (&envline[16]));
- else if (memcmp (envline, "MMAP_THRESHOLD_", 15) == 0)
- __libc_mallopt (M_MMAP_THRESHOLD, atoi (&envline[16]));
- }
- break;
- default:
- break;
- }
- }
- }
- if (s && s[0])
- {
- __libc_mallopt (M_CHECK_ACTION, (int) (s[0] - '0'));
- if (check_action != 0)
- __malloc_check_init ();
- }
void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook);
if (hook != NULL)
(*hook)();
diff --git a/tunables/tunable-list.h b/tunables/tunable-list.h
index e5083d5..0554420 100644
--- a/tunables/tunable-list.h
+++ b/tunables/tunable-list.h
@@ -1,8 +1,12 @@
typedef enum
{
GLIBC_MALLOC,
+ GLIBC_MALLOC_CHECK,
+ GLIBC_MALLOC_TOP_PAD,
+ GLIBC_MALLOC_PERTURB,
GLIBC_MALLOC_MMAP_THRESHOLD,
GLIBC_MALLOC_TRIM_THRESHOLD,
+ GLIBC_MALLOC_MMAP_MAX,
GLIBC_MALLOC_ARENA_MAX,
GLIBC_MALLOC_ARENA_TEST,
TUNABLES_MAX
diff --git a/tunables/tunables.c b/tunables/tunables.c
index 2e1157f..f0acd84 100644
--- a/tunables/tunables.c
+++ b/tunables/tunables.c
@@ -33,10 +33,15 @@ struct _tunable
{
char *name;
char *alias;
- void *val;
- size_t size;
- tunable_type_t type;
+ union
+ {
+ int ns_size;
+ tunable_setter_t set;
+ } data;
+#define set data.set
+#define ns_size data.ns_size
bool initialized;
+ bool enable_secure;
};
/* The full list of tunables. */
@@ -46,30 +51,14 @@ static tunable_t tunable_list[TUNABLES_MAX];
void
tunables_namespace_begin (tunable_id_t id, size_t size)
{
- tunable_list[id].size = size;
-}
-
-/* Set the value of a tunable from its environment variable(s). */
-static void
-tunable_set (tunable_t *t, const char *val)
-{
- switch (t->type & ~TUNABLE_TYPE_SECURE)
- {
- case TUNABLE_TYPE_SIZE_T:
- *(size_t *) t->val = strtoul (val, NULL, 0);
- case TUNABLE_TYPE_STRING:
- memcpy (t->val, val, t->size);
- default:
- __builtin_trap ();
- }
- t->initialized = true;
+ tunable_list[id].ns_size = size;
}
/* Initialize all tunables in the namespace group specified by ID. */
void
tunables_init (tunable_id_t id)
{
- int end = tunable_list[id].size;
+ int end = tunable_list[id].ns_size;
/* Traverse through the environment to find environment variables we may need
to set. */
@@ -86,17 +75,16 @@ tunables_init (tunable_id_t id)
if (envline[len] == '\0')
continue;
- for (int i = id; i < end; i++)
+ for (int i = id + 1; i < end; i++)
{
/* Skip over tunables that are either initialized or are not safe to
load for setuid binaries. */
- if ((__libc_enable_secure
- && (tunable_list[id].type & TUNABLE_TYPE_SECURE) == 0)
- || tunable_list[id].initialized)
+ if ((__libc_enable_secure && !tunable_list[i].enable_secure)
+ || tunable_list[i].initialized)
continue;
- const char *name = tunable_list[id].name;
- const char *alias = tunable_list[id].alias;
+ const char *name = tunable_list[i].name;
+ const char *alias = tunable_list[i].alias;
char *val = NULL;
if (memcmp (envline, name, MIN(len, strlen (name))) == 0)
@@ -106,7 +94,8 @@ tunables_init (tunable_id_t id)
if (val != NULL)
{
- tunable_set (&tunable_list[id], val);
+ tunable_list[i].set (val);
+ tunable_list[i].initialized = true;
break;
}
}
@@ -117,11 +106,10 @@ tunables_init (tunable_id_t id)
/* Initialize a tunable and set its value via the set environment variable. */
void
tunable_register (tunable_id_t id, const char *name, const char *alias,
- void *val, size_t size, tunable_type_t type)
+ tunable_setter_t set_func, bool secure)
{
tunable_list[id].name = __strdup (name);
tunable_list[id].alias = alias ? __strdup (alias) : NULL;
- tunable_list[id].val = val;
- tunable_list[id].size = size;
- tunable_list[id].type = type;
+ tunable_list[id].set = set_func;
+ tunable_list[id].enable_secure = secure;
}
diff --git a/tunables/tunables.h b/tunables/tunables.h
index 448c5d0..4143dc5 100644
--- a/tunables/tunables.h
+++ b/tunables/tunables.h
@@ -20,36 +20,51 @@
#include "tunable-list.h"
-typedef enum
-{
- TUNABLE_TYPE_SECURE,
- TUNABLE_TYPE_SIZE_T = 1 << 1,
- TUNABLE_TYPE_STRING = 1 << 2
-} tunable_type_t;
-
+typedef void (*tunable_setter_t) (const char *);
typedef struct _tunable tunable_t;
+extern void tunables_namespace_begin (tunable_id_t, size_t);
+extern void tunable_register (tunable_id_t, const char *, const char *,
+ tunable_setter_t, bool);
+extern void tunables_init (tunable_id_t);
+
/* Build a full tunable name from a top namespace, tunable namespace and the
id. */
-#define FULL_NAME(top,ns,id) (top ## _ ## ns ## _ ## id)
+#define FULL_NAME(top,ns,id) FULL_NAME1 (top,ns,id)
+#define FULL_NAME1(top,ns,id) (top ## _ ## ns ## _ ## id)
+
#define FULL_NAME_S(top,ns,id) (#top "_" #ns "_" #id)
+#define NS_NAME(top, ns) NS_NAME1(top, ns)
+#define NS_NAME1(top, ns) (top ## _ ## ns)
+
/* Start registering tunables in the current namespace. */
#define TUNABLES_NAMESPACE_BEGIN(size) \
- tunables_namespace_begin (TUNABLE_NAMESPACE, size)
+ tunables_namespace_begin (NS_NAME(TOP_NAMESPACE, TUNABLE_NAMESPACE), size)
/* Register a tunable. This macro validates that the call is OK and then calls
tunable_init to do the real work of adding the tunable and setting its value
based on its environment variable(s). */
-#define TUNABLE_REGISTER(id,alias,val,size,type) \
+#define TUNABLE_REGISTER(id,alias,set) \
+({ \
+ tunable_register (FULL_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
+ FULL_NAME_S (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
+ (alias), (set), false); \
+ \
+})
+
+/* Does exactly the same thing as TUNABLE_REGISTER, except that it allows the
+ tunable to look for environment variable values even for setuid binaries.
+ This is a separate macro and not just another parameter in TUNABLE_REGISTER
+ to avoid accidentally setting a secure flag where it is not required. */
+#define TUNABLE_REGISTER_SECURE(id,alias,set) \
({ \
- static_assert (FULL_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, id) \
- < TUNABLES_MAX); \
tunable_register (FULL_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
FULL_NAME_S (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
- (alias), (val), (size), (type)); \
+ (alias), (set), true); \
\
})
+/* Initialize tunables in the namespace. */
#define TUNABLES_NAMESPACE_INIT() \
- tunables_init (TUNABLE_NAMESPACE, size)
+ tunables_init (NS_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE))
diff --git a/tunables/tunables.list b/tunables/tunables.list
index 3ef02c6..4ab93e4 100644
--- a/tunables/tunables.list
+++ b/tunables/tunables.list
@@ -1,7 +1,11 @@
GLIBC {
MALLOC {
+ CHECK
+ TOP_PAD
+ PERTURB
MMAP_THRESHOLD
TRIM_THRESHOLD
+ MMAP_MAX
ARENA_MAX
ARENA_TEST
}
-----------------------------------------------------------------------
Summary of changes:
malloc/arena.c | 168 +++++++++++++++++++----------------------------
tunables/tunable-list.h | 4 +
tunables/tunables.c | 52 ++++++---------
tunables/tunables.h | 43 ++++++++----
tunables/tunables.list | 4 +
5 files changed, 125 insertions(+), 146 deletions(-)
hooks/post-receive
--
GNU C Library master sources