From 246bd926488b15fcf9867c2a9372a8c173567ffe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C5=99emysl=20Janouch?=
Date: Tue, 14 Jul 2015 23:39:40 +0200
Subject: [PATCH] Allow str_map siphash key randomization
---
liberty.c | 117 +++++++++++++++++++++++++++++++++++-------------------
1 file changed, 76 insertions(+), 41 deletions(-)
diff --git a/liberty.c b/liberty.c
index ad1efba..41e4c6e 100644
--- a/liberty.c
+++ b/liberty.c
@@ -659,6 +659,80 @@ error_propagate (struct error **destination, struct error *source)
*destination = source;
}
+// --- File descriptor utilities -----------------------------------------------
+
+static void
+set_cloexec (int fd)
+{
+ soft_assert (fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC) != -1);
+}
+
+static bool
+set_blocking (int fd, bool blocking)
+{
+ int flags = fcntl (fd, F_GETFL);
+ hard_assert (flags != -1);
+
+ bool prev = !(flags & O_NONBLOCK);
+ if (blocking)
+ flags &= ~O_NONBLOCK;
+ else
+ flags |= O_NONBLOCK;
+
+ hard_assert (fcntl (fd, F_SETFL, flags) != -1);
+ return prev;
+}
+
+static void
+xclose (int fd)
+{
+ while (close (fd) == -1)
+ if (!soft_assert (errno == EINTR))
+ break;
+}
+
+// --- Randomness --------------------------------------------------------------
+
+static bool
+random_bytes (void *output, size_t len, struct error **e)
+{
+ bool result = false;
+ int fd = open ("/dev/urandom", O_RDONLY);
+ ssize_t got = 0;
+
+ if (fd < 0)
+ {
+ error_set (e, "%s: %s", "open", strerror (errno));
+ return false;
+ }
+ else if ((got = read (fd, output, len)) < 0)
+ error_set (e, "%s: %s", "read", strerror (errno));
+ else if (got != (ssize_t) len)
+ error_set (e, "can't get enough bytes from the device");
+ else
+ result = true;
+
+ xclose (fd);
+ return result;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+static unsigned char g_siphash_key[16] = "SipHash 2-4 key!";
+
+static inline void
+siphash_wrapper_randomize (void)
+{
+ // I guess there's no real need to be this paranoic, so we ignore failures
+ soft_assert (random_bytes (g_siphash_key, sizeof g_siphash_key, NULL));
+}
+
+static inline uint64_t
+siphash_wrapper (const void *m, size_t len)
+{
+ return siphash (g_siphash_key, m, len);
+}
+
// --- String hash map ---------------------------------------------------------
// The most basic map (or associative array).
@@ -728,24 +802,17 @@ str_map_free (struct str_map *self)
self->map = NULL;
}
-static uint64_t
-str_map_hash (const char *s, size_t len)
-{
- static unsigned char key[16] = "SipHash 2-4 key!";
- return siphash (key, (const void *) s, len);
-}
-
static uint64_t
str_map_pos (struct str_map *self, const char *s)
{
size_t mask = self->alloc - 1;
- return str_map_hash (s, strlen (s)) & mask;
+ return siphash_wrapper (s, strlen (s)) & mask;
}
static uint64_t
str_map_link_hash (struct str_map_link *self)
{
- return str_map_hash (self->key, self->key_length);
+ return siphash_wrapper (self->key, self->key_length);
}
static void
@@ -959,38 +1026,6 @@ str_map_unset_iter_free (struct str_map_unset_iter *self)
str_map_shrink (self->iter.map);
}
-// --- File descriptor utilities -----------------------------------------------
-
-static void
-set_cloexec (int fd)
-{
- soft_assert (fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC) != -1);
-}
-
-static bool
-set_blocking (int fd, bool blocking)
-{
- int flags = fcntl (fd, F_GETFL);
- hard_assert (flags != -1);
-
- bool prev = !(flags & O_NONBLOCK);
- if (blocking)
- flags &= ~O_NONBLOCK;
- else
- flags |= O_NONBLOCK;
-
- hard_assert (fcntl (fd, F_SETFL, flags) != -1);
- return prev;
-}
-
-static void
-xclose (int fd)
-{
- while (close (fd) == -1)
- if (!soft_assert (errno == EINTR))
- break;
-}
-
// --- Event loop --------------------------------------------------------------
#ifdef LIBERTY_WANT_POLLER