[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH] Dynamically initialize MALLOC_PERTURB_ when loader starts.



Seriously overengineer the initialization of the env variables we pass
to loader so that we can set MALLOC_PERTURB_ to a random number.  Is
this worth it - who can say?
---
 loader/init.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/loader/init.c b/loader/init.c
index f5c3dbf..e79691f 100644
--- a/loader/init.c
+++ b/loader/init.c
@@ -455,6 +455,66 @@ static void setupBacktrace(void)
     backtrace(&array, 1);
 }
 
+static char *setupMallocPerturb(char *value)
+{
+    FILE *f;
+    unsigned char x;
+    size_t rc;
+    char *ret = NULL;
+    
+    f = fopen("/dev/urandom", "r");
+    if (!f)
+        return NULL;
+
+    rc = fread(&x, 1, 1, f);
+    fclose(f);
+    if (rc < 1)
+        return NULL;
+
+    rc = asprintf(&ret, "MALLOC_PERTURB_=%hhu", x);
+    if (rc < 0)
+        return NULL;
+    return ret;
+}
+
+/* these functions return a newly allocated string that never gets freed;
+ * their lifetime is essentially that of main(), and we'd have to track which
+ * are allocated and which aren't, which is pretty pointless... */
+typedef char *(*setupEnvCallback)(char *entry);
+
+static void setupEnv(void)
+{
+    struct {
+        char *name;
+        setupEnvCallback cb;
+    } setupEnvCallbacks[] = {
+        { "MALLOC_PERTURB_", setupMallocPerturb },
+        { NULL, NULL }
+    };
+    int x;
+
+    /* neither array is very big, so this algorithm isn't so bad.  If env[]
+     * gets bigger for some reason, we should probably just alphebatize both
+     * (manually) and then only initialize y one time.
+     */
+    for (x = 0; setupEnvCallbacks[x].name != NULL; x++) {
+        int y;
+        int l = strlen(setupEnvCallbacks[x].name) + 1;
+        char cmpstr[l + 1];
+
+        strncpy(cmpstr, setupEnvCallbacks[x].name, l);
+        strcat(cmpstr, "=");
+
+        for (y = 0; env[y] != NULL; y++) {
+            if (!strncmp(env[y], cmpstr, l)) {
+                char *new = setupEnvCallbacks[x].cb(env[y] + l);
+                if (new)
+                    env[y] = new;
+            }
+        }
+    }
+}
+
 int main(int argc, char **argv) {
     pid_t installpid, childpid;
     int waitStatus;
@@ -502,6 +562,9 @@ int main(int argc, char **argv) {
     /* set up signal handler */
     setupBacktrace();
 
+    /* set up any environment variables that aren't totally static */
+    setupEnv();
+
     printstr("\nGreetings.\n");
 
     printf("anaconda installer init version %s starting\n", VERSION);
-- 
1.7.2.3


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]