From af366b20a32902e5e3aa222d3f087ff085901a49 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 12 Aug 2019 21:37:19 +0100 Subject: [PATCH] [Minor] Fix more alignment and ubsan issues --- src/libcryptobox/base64/ref.c | 19 ++++++++++++------- src/libserver/rspamd_symcache.c | 2 +- src/libserver/url.c | 2 +- src/libutil/str_util.h | 32 +++++++++++++++++++++++--------- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/libcryptobox/base64/ref.c b/src/libcryptobox/base64/ref.c index 541e4e929..c7cefd761 100644 --- a/src/libcryptobox/base64/ref.c +++ b/src/libcryptobox/base64/ref.c @@ -28,13 +28,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" +#include "libutil/util.h" extern const uint8_t base64_table_dec[256]; #define INNER_LOOP_64 do { \ + uint64_t str, res, dec; \ + bool aligned = rspamd_is_aligned_as(c, str); \ + bool oaligned = rspamd_is_aligned_as(o, res); \ while (inlen >= 13) { \ - uint64_t str, res, dec; \ - memcpy(&str, c, sizeof(str)); \ + if (aligned) { str = *(uint64_t *)c; } else {memcpy(&str, c, sizeof(str)); } \ str = GUINT64_TO_BE(str); \ if ((dec = base64_table_dec[str >> 56]) > 63) { \ break; \ @@ -69,7 +72,7 @@ extern const uint8_t base64_table_dec[256]; } \ res |= dec << 16; \ res = GUINT64_FROM_BE(res); \ - *(uint64_t *)o = res; \ + if (oaligned) {*(uint64_t *)o = res;} else {memcpy(o, &res, sizeof(res));} \ c += 8; \ o += 6; \ outl += 6; \ @@ -78,9 +81,11 @@ extern const uint8_t base64_table_dec[256]; } while (0) #define INNER_LOOP_32 do { \ + uint32_t str, res, dec; \ + bool aligned = rspamd_is_aligned_as(c, str); \ + bool oaligned = rspamd_is_aligned_as(o, res); \ while (inlen >= 8) { \ - uint32_t str, res, dec; \ - memcpy(&str, c, sizeof(str)); \ + if (aligned) { str = *(uint32_t *)c; } else {memcpy(&str, c, sizeof(str)); } \ str = GUINT32_TO_BE(str); \ if ((dec = base64_table_dec[str >> 24]) > 63) { \ break; \ @@ -99,7 +104,7 @@ extern const uint8_t base64_table_dec[256]; } \ res |= dec << 8; \ res = GUINT32_FROM_BE(res); \ - *(uint32_t *)o = res; \ + if (oaligned) {*(uint32_t *)o = res;} else {memcpy(o, &res, sizeof(res));} \ c += 4; \ o += 3; \ outl += 3; \ @@ -150,7 +155,7 @@ repeat: break; } *o++ = carry | (q >> 4); - carry = q << 4; + carry = (uint8_t)(q << 4); leftover++; outl++; diff --git a/src/libserver/rspamd_symcache.c b/src/libserver/rspamd_symcache.c index ad5bd4e1c..f91aa9a22 100644 --- a/src/libserver/rspamd_symcache.c +++ b/src/libserver/rspamd_symcache.c @@ -1232,7 +1232,7 @@ rspamd_symcache_new (struct rspamd_config *cfg) cache->cfg = cfg; cache->cksum = 0xdeadbabe; cache->peak_cb = -1; - cache->id = rspamd_random_uint64_fast (); + cache->id = (guint)rspamd_random_uint64_fast (); return cache; } diff --git a/src/libserver/url.c b/src/libserver/url.c index 240af9d03..ef59b6da0 100644 --- a/src/libserver/url.c +++ b/src/libserver/url.c @@ -1188,7 +1188,7 @@ rspamd_web_parse (struct http_parser_url *u, const gchar *str, gsize len, (*flags) |= RSPAMD_URL_FLAG_IDN; guint i = 0; - U8_NEXT (p, i, last - p, uc); + U8_NEXT (((const guchar *)p), i, last - p, uc); if (uc < 0) { /* Bad utf8 */ diff --git a/src/libutil/str_util.h b/src/libutil/str_util.h index c820bd10c..a1f980526 100644 --- a/src/libutil/str_util.h +++ b/src/libutil/str_util.h @@ -20,6 +20,8 @@ #include "ucl.h" #include "fstring.h" +#include + #ifdef __cplusplus extern "C" { #endif @@ -422,23 +424,35 @@ gsize rspamd_memspn (const gchar *s, const gchar *e, gsize len); /* https://graphics.stanford.edu/~seander/bithacks.html#HasMoreInWord */ #define rspamd_str_hasmore(x, n) ((((x)+~0UL/255*(127-(n)))|(x))&~0UL/255*128) +/* + * Check if a pointer is aligned; n must be power of two + */ +#define rspamd_is_aligned(p, n) (((uintptr_t)(p) & ((uintptr_t)(n) - 1)) == 0) +#define rspamd_is_aligned_as(p, v) rspamd_is_aligned(p, _Alignof(__typeof((v)))) static inline gboolean -rspamd_str_has_8bit (const guchar *beg, gsize len) { +rspamd_str_has_8bit (const guchar *beg, gsize len) +{ unsigned long *w; - gsize i, leftover = len % sizeof (*w); + gsize i, leftover; - w = (unsigned long *) beg; + if (rspamd_is_aligned_as (beg, *w)) { + leftover = len % sizeof (*w); + w = (unsigned long *) beg; - for (i = 0; i < len / sizeof (*w); i++) { - if (rspamd_str_hasmore (*w, 127)) { - return TRUE; + for (i = 0; i < len / sizeof (*w); i++) { + if (rspamd_str_hasmore (*w, 127)) { + return TRUE; + } + + w++; } - w++; + beg = (const guchar *) w; + } + else { + leftover = len; } - - beg = (const guchar *) w; for (i = 0; i < leftover; i++) { if (beg[i] > 127) { -- 2.39.5