commit af366b2: [Minor] Fix more alignment and ubsan issues

Vsevolod Stakhov vsevolod at highsecure.ru
Mon Aug 12 20:42:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-08-12 21:37:19 +0100
URL: https://github.com/rspamd/rspamd/commit/af366b20a32902e5e3aa222d3f087ff085901a49 (HEAD -> master)

[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 <stdalign.h>
+
 #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) {


More information about the Commits mailing list