]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
siphash24: change result argument to uint64_t 1916/head
authorMartin Pitt <martin.pitt@ubuntu.com>
Mon, 16 Nov 2015 08:21:20 +0000 (09:21 +0100)
committerDaniel Mack <daniel@zonque.org>
Mon, 16 Nov 2015 14:20:29 +0000 (15:20 +0100)
Change the "out" parameter from uint8_t[8] to uint64_t. On architectures which
enforce pointer alignment this fixes crashes when we previously cast an
unaligned array to uint64_t*, and on others this should at least improve
performance as the compiler now aligns these properly.

This also simplifies the code in most cases by getting rid of typecasts. The
only place which we can't change is struct duid's en.id, as that is _packed_
and public API, so we can't enforce alignment of the "id" field and have to
use memcpy instead.

17 files changed:
src/basic/hashmap.c
src/basic/siphash24.c
src/basic/siphash24.h
src/import/pull-common.c
src/journal/journald-rate-limit.c
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/network-internal.c
src/libsystemd-network/network-internal.h
src/libsystemd-network/sd-dhcp-server.c
src/libsystemd-network/sd-ipv4ll.c
src/libsystemd-network/test-dhcp-server.c
src/libsystemd/sd-bus/bus-bloom.c
src/network/networkd-ipv4ll.c
src/network/networkd-netdev.c
src/nspawn/nspawn-network.c
src/test/test-siphash24.c
src/udev/net/link-config.c

index 4109a08c6cafcc426bb4b18087122bed645481a1..d88ceb40aa93be93b55f48aaa1ec6f45755f8947 100644 (file)
@@ -380,7 +380,7 @@ static unsigned base_bucket_hash(HashmapBase *h, const void *p) {
 
         h->hash_ops->hash(p, &state);
 
-        siphash24_finalize((uint8_t*)&hash, &state);
+        siphash24_finalize(&hash, &state);
 
         return (unsigned) (hash % n_buckets(h));
 }
index 1da2d1a4103549733049d273ee2902d672e3431d..d7640d395ded78e0827bfdd79da180ed3a1f6fed 100644 (file)
@@ -141,7 +141,7 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
         }
 }
 
-void siphash24_finalize(uint8_t out[8], struct siphash *state) {
+void siphash24_finalize(uint64_t *out, struct siphash *state) {
         uint64_t b;
 
         b = state->padding | (( ( uint64_t )state->inlen ) << 56);
@@ -174,7 +174,7 @@ void siphash24_finalize(uint8_t out[8], struct siphash *state) {
 }
 
 /* SipHash-2-4 */
-void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) {
+void siphash24(uint64_t *out, const void *_in, size_t inlen, const uint8_t k[16]) {
         struct siphash state;
 
         siphash24_init(&state, k);
index 6c5cd98ee82a83ee12c992926580d1af26f8825c..dc08077d535ccefca2c7c31e67921de516bf5a73 100644 (file)
@@ -14,6 +14,6 @@ struct siphash {
 
 void siphash24_init(struct siphash *state, const uint8_t k[16]);
 void siphash24_compress(const void *in, size_t inlen, struct siphash *state);
-void siphash24_finalize(uint8_t out[8], struct siphash *state);
+void siphash24_finalize(uint64_t *out, struct siphash *state);
 
-void siphash24(uint8_t out[8], const void *in, size_t inlen, const uint8_t k[16]);
+void siphash24(uint64_t *out, const void *in, size_t inlen, const uint8_t k[16]);
index d6567ba7eec6c4f9c1991d65b5ddac4d176acd8c..16b0c6160fbd1f8145b6df57ea1b45c1ceb5b8b6 100644 (file)
@@ -165,7 +165,7 @@ static int hash_url(const char *url, char **ret) {
 
         assert(url);
 
-        siphash24((uint8_t *) &h, url, strlen(url), k.bytes);
+        siphash24(&h, url, strlen(url), k.bytes);
         if (asprintf(ret, "%"PRIx64, h) < 0)
                 return -ENOMEM;
 
index 434ddc8ac91e7815242cfacdc4076685ad55a098..ad78d0929441f95f42493f1ba02766aa51f60ea7 100644 (file)
@@ -162,7 +162,7 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r,
 
         siphash24_init(&state, r->hash_key);
         string_hash_func(g->id, &state);
-        siphash24_finalize((uint8_t*)&g->hash, &state);
+        siphash24_finalize(&g->hash, &state);
 
         journal_rate_limit_vacuum(r, ts);
 
@@ -230,7 +230,7 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
 
         siphash24_init(&state, r->hash_key);
         string_hash_func(id, &state);
-        siphash24_finalize((uint8_t*)&h, &state);
+        siphash24_finalize(&h, &state);
         g = r->buckets[h % BUCKETS_MAX];
 
         LIST_FOREACH(bucket, g, g)
index 51ee7bcce471dffa360daf3a963e64365b93db70..368525c40ac2de3e6dd3bdcdb11ba65ccf0c8f43 100644 (file)
@@ -35,6 +35,7 @@
 
 int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
         sd_id128_t machine_id;
+        uint64_t hash;
         int r;
 
         assert(duid);
@@ -50,8 +51,9 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
         *len = sizeof(duid->type) + sizeof(duid->en);
 
         /* a bit of snake-oil perhaps, but no need to expose the machine-id
-           directly */
-        siphash24(duid->en.id, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
+           directly; duid->en.id might not be aligned, so we need to copy */
+        siphash24(&hash, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
+        memcpy(duid->en.id, &hash, sizeof(duid->en.id));
 
         return 0;
 }
@@ -84,10 +86,10 @@ int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_i
         }
 
         if (name)
-                siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes);
+                siphash24(&id, name, strlen(name), HASH_KEY.bytes);
         else
                 /* fall back to MAC address if no predictable name available */
-                siphash24((uint8_t*)&id, mac, mac_len, HASH_KEY.bytes);
+                siphash24(&id, mac, mac_len, HASH_KEY.bytes);
 
         /* fold into 32 bits */
         unaligned_write_be32(_id, (id & 0xffffffff) ^ (id >> 32));
index 52d76e443ec5ad25562fcbbdda9daeb369faa3b1..ab20b6065a3b1b40b2237028c90ff19bcaf3114e 100644 (file)
@@ -56,7 +56,7 @@ const char *net_get_name(struct udev_device *device) {
 
 #define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
 
-int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]) {
+int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result) {
         size_t l, sz = 0;
         const char *name = NULL;
         int r;
index d5d4ef42f246face3931d2f23fd9bd13aa86ca57..d516f2dafd55218ae0e61e87902b03ee2054e256 100644 (file)
@@ -62,7 +62,7 @@ int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
                          const char *section, unsigned section_line, const char *lvalue,
                          int ltype, const char *rvalue, void *data, void *userdata);
 
-int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]);
+int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
 const char *net_get_name(struct udev_device *device);
 
 void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
index 8d0d9955c332d14aac09d816c819ac6c86ae3146..eeb59bb3dadce790e7f70a95409b8793dab3fb2d 100644 (file)
@@ -753,7 +753,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
 
                         siphash24_init(&state, HASH_KEY.bytes);
                         client_id_hash_func(&req->client_id, &state);
-                        siphash24_finalize((uint8_t*)&hash, &state);
+                        siphash24_finalize(&hash, &state);
                         next_offer = hash % server->pool_size;
 
                         for (i = 0; i < server->pool_size; i++) {
index 0d915e20e7fd8d6483031420979c6014d9ec9323..e69b1864d7f7c6a11e269efd2171e9f23bf491ad 100644 (file)
@@ -143,15 +143,15 @@ int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) {
         assert_return(ll, -EINVAL);
 
         if (!ll->random_data) {
-                uint8_t seed[8];
+                uint64_t seed;
 
                 /* If no random data is set, generate some from the MAC */
-                siphash24(seed, &addr->ether_addr_octet,
+                siphash24(&seed, &addr->ether_addr_octet,
                           ETH_ALEN, HASH_KEY.bytes);
 
                 assert_cc(sizeof(unsigned) <= 8);
 
-                r = sd_ipv4ll_set_address_seed(ll, *(unsigned*)seed);
+                r = sd_ipv4ll_set_address_seed(ll, (unsigned)seed);
                 if (r < 0)
                         return r;
         }
index 1a5c8c460539e8e4cfb924cde8f88e23eb3f92c7..62fdec46dab03e6bb5e9dfc9e6028d4143185ff1 100644 (file)
@@ -204,7 +204,7 @@ static uint64_t client_id_hash_helper(DHCPClientId *id, uint8_t key[HASH_KEY_SIZ
 
         siphash24_init(&state, key);
         client_id_hash_func(id, &state);
-        siphash24_finalize((uint8_t*)&hash, &state);
+        siphash24_finalize(&hash, &state);
 
         return hash;
 }
index 91fab90cb0b8a2e4bda5432af88b6a1684aab32b..a592ff50cfd28ea7523814f7c637a6b8c4c6b8f7 100644 (file)
@@ -45,7 +45,7 @@ static void bloom_add_data(
                 const void *data,      /* Data to hash */
                 size_t n) {            /* Size of data to hash in bytes */
 
-        uint8_t h[8];
+        uint64_t h;
         uint64_t m;
         unsigned w, i, c = 0;
         unsigned hash_index;
@@ -72,11 +72,11 @@ static void bloom_add_data(
 
                 for (d = 0; d < w; d++) {
                         if (c <= 0) {
-                                siphash24(h, data, n, hash_keys[hash_index++].bytes);
+                                siphash24(&h, data, n, hash_keys[hash_index++].bytes);
                                 c += 8;
                         }
 
-                        p = (p << 8ULL) | (uint64_t) h[8 - c];
+                        p = (p << 8ULL) | (uint64_t) ((uint8_t *)&h)[8 - c];
                         c--;
                 }
 
index ed0d861e7af5446f752c90855baf336262e92a83..506654b5d7cbf3e6a62ebbddaca2f5b10c3c7dda 100644 (file)
@@ -201,7 +201,7 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
 }
 
 int ipv4ll_configure(Link *link) {
-        uint8_t seed[8];
+        uint64_t seed;
         int r;
 
         assert(link);
@@ -215,11 +215,11 @@ int ipv4ll_configure(Link *link) {
         }
 
         if (link->udev_device) {
-                r = net_get_unique_predictable_data(link->udev_device, seed);
+                r = net_get_unique_predictable_data(link->udev_device, &seed);
                 if (r >= 0) {
                         assert_cc(sizeof(unsigned) <= 8);
 
-                        r = sd_ipv4ll_set_address_seed(link->ipv4ll, *(unsigned *)seed);
+                        r = sd_ipv4ll_set_address_seed(link->ipv4ll, (unsigned)seed);
                         if (r < 0)
                                 return r;
                 }
index dd0b400c6a0a8cb1337837e9b7cd4bc7c6582c33..081e299d8267de78af4ce2bc540c752a6d2b491c 100644 (file)
@@ -411,7 +411,7 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) {
 
 int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
         _cleanup_free_ struct ether_addr *mac = NULL;
-        uint8_t result[8];
+        uint64_t result;
         size_t l, sz;
         uint8_t *v;
         int r;
@@ -438,10 +438,10 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
 
         /* Let's hash the host machine ID plus the container name. We
          * use a fixed, but originally randomly created hash key here. */
-        siphash24(result, v, sz, HASH_KEY.bytes);
+        siphash24(&result, v, sz, HASH_KEY.bytes);
 
         assert_cc(ETH_ALEN <= sizeof(result));
-        memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+        memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
 
         /* see eth_random_addr in the kernel */
         mac->ether_addr_octet[0] &= 0xfe;        /* clear multicast bit */
index c71552879d83e38aa4fb609302470669174829c1..92dfb945e00f8d45b6bc96f59663c68f450dc56f 100644 (file)
@@ -47,7 +47,7 @@ static int generate_mac(
                 sd_id128_t hash_key,
                 uint64_t idx) {
 
-        uint8_t result[8];
+        uint64_t result;
         size_t l, sz;
         uint8_t *v, *i;
         int r;
@@ -74,10 +74,10 @@ static int generate_mac(
 
         /* Let's hash the host machine ID plus the container name. We
          * use a fixed, but originally randomly created hash key here. */
-        siphash24(result, v, sz, hash_key.bytes);
+        siphash24(&result, v, sz, hash_key.bytes);
 
         assert_cc(ETH_ALEN <= sizeof(result));
-        memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+        memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
 
         /* see eth_random_addr in the kernel */
         mac->ether_addr_octet[0] &= 0xfe;        /* clear multicast bit */
index 2402da6a6f25c440e32d915ea097caf4b30eac55..e5a989cdad739e06fb495629955b30462b171625 100644 (file)
@@ -34,7 +34,7 @@ int main(int argc, char *argv[]) {
         uint64_t out = 0;
         unsigned i, j;
 
-        siphash24((uint8_t *)&out, in, sizeof(in), key);
+        siphash24(&out, in, sizeof(in), key);
         assert_se(out == htole64(0xa129ca6149be45e5));
 
         /* verify the internal state as given in the above paper */
@@ -48,7 +48,7 @@ int main(int argc, char *argv[]) {
         assert_se(state.v1 == 0x0d52f6f62a4f59a4);
         assert_se(state.v2 == 0x634cb3577b01fd3d);
         assert_se(state.v3 == 0xa5224d6f55c7d9c8);
-        siphash24_finalize((uint8_t*)&out, &state);
+        siphash24_finalize(&out, &state);
         assert_se(out == htole64(0xa129ca6149be45e5));
         assert_se(state.v0 == 0xf6bcd53893fecff1);
         assert_se(state.v1 == 0x54b9964c7ea0d937);
@@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
                         siphash24_compress(in, i, &state);
                         siphash24_compress(&in[i], j - i, &state);
                         siphash24_compress(&in[j], sizeof(in) - j, &state);
-                        siphash24_finalize((uint8_t*)&out, &state);
+                        siphash24_finalize(&out, &state);
                         assert_se(out == htole64(0xa129ca6149be45e5));
                 }
         }
index 776674e9945369e822beaa23b1d1ceacabb7d5a3..77d9bf995ad63f9d7fc0ead1b0891df8b5a40ff4 100644 (file)
@@ -354,14 +354,14 @@ static int get_mac(struct udev_device *device, bool want_random,
         if (want_random)
                 random_bytes(mac->ether_addr_octet, ETH_ALEN);
         else {
-                uint8_t result[8];
+                uint64_t result;
 
-                r = net_get_unique_predictable_data(device, result);
+                r = net_get_unique_predictable_data(device, &result);
                 if (r < 0)
                         return r;
 
                 assert_cc(ETH_ALEN <= sizeof(result));
-                memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+                memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
         }
 
         /* see eth_random_addr in the kernel */