Commit 956955a0 authored by Ondřej Surý's avatar Ondřej Surý Committed by Daniel Salzman

Fix unaligned memory access and other errors from UBSAN

parent 7279251a
......@@ -67,16 +67,18 @@ static int reduce_dist(hhash_t *t, int idx, int *empty)
* The function should be repeated until we move the free bucket
* in the vicinity of the target index.
*/
unsigned cur = (t->size + *empty - dist) % t->size; /* bucket to be vacated */
unsigned off = HOP_NEXT(t->item[cur].hop); /* offset of first valid bucket */
if (t->item[cur].hop != 0 && off < dist) { /* only offsets in <s, f> are interesting */
unsigned hit = (cur + off) % t->size; /* this item will be displaced to [f] */
t->item[*empty].d = t->item[hit].d; /* displace data */
t->item[hit].d = NULL;
t->item[cur].hop &= ~HOP_BIT(off); /* displace bitvector index */
t->item[cur].hop |= HOP_BIT(dist);
*empty = hit;
return idx - (dist - off); /* new distance */
unsigned cur = (t->size + *empty - dist) % t->size; /* bucket to be vacated */
if (t->item[cur].hop != 0) { /* only offsets in <s, f> are interesting */
unsigned off = HOP_NEXT(t->item[cur].hop); /* offset of first valid bucket */
if (off < dist) {
unsigned hit = (cur + off) % t->size; /* this item will be displaced to [f] */
t->item[*empty].d = t->item[hit].d; /* displace data */
t->item[hit].d = NULL;
t->item[cur].hop &= ~HOP_BIT(off); /* displace bitvector index */
t->item[cur].hop |= HOP_BIT(dist);
*empty = hit;
return idx - (dist - off); /* new distance */
}
}
--dist;
}
......
......@@ -3,6 +3,7 @@
* by its author, Austin Appleby.
*/
#include <string.h>
#include "contrib/murmurhash3/murmurhash3.h"
static inline uint32_t fmix(uint32_t h)
......@@ -24,7 +25,7 @@ static inline uint32_t rotl32(uint32_t x, int8_t r)
uint32_t hash(const char* data, size_t len_)
{
const int len = (int) len_;
const int nblocks = len / 4;
const int nblocks = len / sizeof(uint32_t);
uint32_t h1 = 0xc062fb4a;
......@@ -34,12 +35,10 @@ uint32_t hash(const char* data, size_t len_)
//----------
// body
const uint32_t * blocks = (const uint32_t*) (data + nblocks * 4);
int i;
for(i = -nblocks; i; i++)
for(int i = 0; i < nblocks; i++)
{
uint32_t k1 = blocks[i];
uint32_t k1;
memcpy(&k1, data + (i * sizeof(uint32_t)), sizeof(uint32_t));
k1 *= c1;
k1 = rotl32(k1, 15);
......
......@@ -180,13 +180,14 @@ static int rrl_classify(char *dst, size_t maxlen, const struct sockaddr_storage
blklen += sizeof(nb);
/* Name */
uint16_t *nlen = (uint16_t *)(dst + blklen);
uint16_t *len_pos = (uint16_t *)(dst + blklen);
blklen += sizeof(uint16_t);
int len = rrl_clsname(dst + blklen, maxlen - blklen, cls, p, z);
if (len < 0) {
return len;
int ret = rrl_clsname(dst + blklen, maxlen - blklen, cls, p, z);
if (ret < 0) {
return ret;
}
*nlen = len;
uint16_t len = ret;
memcpy(len_pos, &len, sizeof(len));
blklen += len;
/* Seed. */
......@@ -253,17 +254,19 @@ static inline unsigned reduce_dist(rrl_table_t *t, unsigned id, unsigned d, unsi
unsigned rd = HOP_LEN - 1;
while (rd > 0) {
unsigned s = (t->size + *f - rd) % t->size; /* bucket to be vacated */
unsigned o = __builtin_ctz(t->arr[s].hop); /* offset of first valid bucket */
if (t->arr[s].hop != 0 && o < rd) { /* only offsets in <s, f> are interesting */
unsigned e = (s + o) % t->size; /* this item will be displaced to [f] */
unsigned keep_hop = t->arr[*f].hop; /* unpredictable padding */
memcpy(t->arr + *f, t->arr + e, sizeof(rrl_item_t));
t->arr[*f].hop = keep_hop;
t->arr[e].cls = CLS_NULL;
t->arr[s].hop &= ~(1<<o);
t->arr[s].hop |= 1<<rd;
*f = e;
return d - (rd - o);
if (t->arr[s].hop != 0) {
unsigned o = __builtin_ctz(t->arr[s].hop); /* offset of first valid bucket */
if (o < rd) { /* only offsets in <s, f> are interesting */
unsigned e = (s + o) % t->size; /* this item will be displaced to [f] */
unsigned keep_hop = t->arr[*f].hop; /* unpredictable padding */
memcpy(t->arr + *f, t->arr + e, sizeof(rrl_item_t));
t->arr[*f].hop = keep_hop;
t->arr[e].cls = CLS_NULL;
t->arr[s].hop &= ~(1<<o);
t->arr[s].hop |= 1<<rd;
*f = e;
return d - (rd - o);
}
}
--rd;
}
......@@ -382,14 +385,16 @@ rrl_item_t *rrl_hash(rrl_table_t *t, const struct sockaddr_storage *a, rrl_req_t
pthread_mutex_lock(&t->ll);
/* Find an exact match in <id, id + HOP_LEN). */
uint16_t *qname = (uint16_t *)(buf + sizeof(uint8_t) + sizeof(uint64_t));
char *qname = buf + sizeof(uint8_t) + sizeof(uint64_t);
uint64_t netblk;
memcpy(&netblk, buf + sizeof(uint8_t), sizeof(netblk));
rrl_item_t match = {
.hop = 0,
.netblk = *((uint64_t *)(buf + 1)),
.netblk = netblk,
.ntok = t->rate * RRL_CAPACITY,
.cls = buf[0],
.flags = RRL_BF_NULL,
.qname = hash((char *)(qname + 1), *qname),
.qname = hash(qname + 1, *qname),
.time = stamp
};
......
This diff is collapsed.
......@@ -6083,7 +6083,8 @@ _match:
case 42:
{
if (s->number64 <= UINT16_MAX) {
*((uint16_t *)rdata_tail) = htons((uint16_t)(s->number64));
uint16_t num16 = htons((uint16_t)s->number64);
memcpy(rdata_tail, &num16, 2);
rdata_tail += 2;
} else {
WARN(ZS_NUMBER16_OVERFLOW);
......@@ -6094,7 +6095,8 @@ _match:
case 43:
{
if (s->number64 <= UINT32_MAX) {
*((uint32_t *)rdata_tail) = htonl((uint32_t)(s->number64));
uint32_t num32 = htonl((uint32_t)s->number64);
memcpy(rdata_tail, &num32, 4);
rdata_tail += 4;
} else {
WARN(ZS_NUMBER32_OVERFLOW);
......
......@@ -374,7 +374,8 @@
}
action _num16_write {
if (s->number64 <= UINT16_MAX) {
*((uint16_t *)rdata_tail) = htons((uint16_t)(s->number64));
uint16_t num16 = htons((uint16_t)s->number64);
memcpy(rdata_tail, &num16, 2);
rdata_tail += 2;
} else {
WARN(ZS_NUMBER16_OVERFLOW);
......@@ -383,7 +384,8 @@
}
action _num32_write {
if (s->number64 <= UINT32_MAX) {
*((uint32_t *)rdata_tail) = htonl((uint32_t)(s->number64));
uint32_t num32 = htonl((uint32_t)s->number64);
memcpy(rdata_tail, &num32, 4);
rdata_tail += 4;
} else {
WARN(ZS_NUMBER32_OVERFLOW);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment