commit - b9f120ef9bd9064c343e73cd65f9f43f4da37892
commit + 4b22351c31db179a117ab4658745bc16ef4ec73f
blob - 7ddcc982461b93dd2cf2cd9e5828959067859c1c
blob + ffe9176a1142b82e308eb15b81e2e33b592a75c1
--- cmake/BuildLuaJIT.cmake
+++ cmake/BuildLuaJIT.cmake
if (ENABLE_UBSAN)
string(JOIN "," NO_SANITIZE_FLAGS
- # lj_str.c
- implicit-integer-sign-change
- # lj_opt_fold.c
- implicit-unsigned-integer-truncation
- # lj_parse.c
+ # Misaligned pseudo-pointers are used to determine
+ # internal variable names inside the `for` cycle.
alignment
- # lj_tab.c
+ # Not interested in float cast overflow errors. These
+ # overflows are handled by special checks after
+ # `lj_num2int()`, etc.
float-cast-overflow
- # lj_gc.c
- function
- # lj_buf.c
- shift
- # lj_obj.h
- unsigned-integer-overflow
- # lj_prng.c
- unsigned-shift-base
- # lj_parse.c
- pointer-overflow
- # The object size sanitizer has no effect at -O0.
- object-size
- # lj_parse.c
+ # NULL checking is disabled because this is not a UB
+ # and raises lots of false-positive fails.
null
- # lj_vmmath.c
- float-divide-by-zero
- integer-divide-by-zero
+ # Not interested in checking arithmetic with NULL.
+ pointer-overflow
+ # Shifts of negative numbers are widely used in
+ # parsing ULEB, cdata arithmetic, vmevent hash
+ # calculation, etc.
+ shift-base
)
+ # GCC has no "function" UB check.
+ if(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ string(JOIN "," NO_SANITIZE_FLAGS
+ ${NO_SANITIZE_FLAGS}
+ # Not interested in function type mismatch errors.
+ function
+ )
+ endif()
+ # Enable UndefinedBehaviorSanitizer support.
+ # This flag enables all supported options (the
+ # documentation on site is not correct about that moment,
+ # unfortunately) except float-divide-by-zero. Floating
+ # point division by zero behaviour is defined without
+ # -ffast-math and uses the IEEE 754 standard on which all
+ # NaN tagging is based.
set(UBSAN_FLAGS "-fsanitize=undefined")
set(UBSAN_FLAGS "-fno-sanitize-recover=undefined")
+ # XXX: To get nicer stack traces in error messages.
+ set(UBSAN_FLAGS "-fno-omit-frame-pointer")
set(UBSAN_FLAGS "-fno-sanitize=${NO_SANITIZE_FLAGS}")
+ set(CFLAGS "${CFLAGS} -DLUAJIT_USE_UBSAN")
set(CFLAGS "${CFLAGS} ${UBSAN_FLAGS}")
set(LDFLAGS "${LDFLAGS} ${UBSAN_FLAGS}")
endif (ENABLE_UBSAN)
blob - f03f959b136b8bd6e5a66bf38bed102c2883f1f7
blob + 2ee1561e6ca7b1d4b792961f3b16f670c41cc34a
--- patches/luajit-v2.1.patch
+++ patches/luajit-v2.1.patch
diff --git a/src/host/buildvm.c b/src/host/buildvm.c
-index 9ee47ada..0cb6be1b 100644
+index ec99e501..d23530c4 100644
--- a/src/host/buildvm.c
+++ b/src/host/buildvm.c
@@ -35,6 +35,10 @@
#include <io.h>
#endif
-
+
+#if LUAJIT_USE_ASAN
+int __lsan_is_turned_off() { return 1; } /* leaks are ok */
+#endif
+
/* ------------------------------------------------------------------------ */
-
+
/* DynASM glue definitions. */
+diff --git a/src/lj_buf.h b/src/lj_buf.h
+index 744e5747..ea299472 100644
+--- a/src/lj_buf.h
++++ b/src/lj_buf.h
+@@ -165,6 +165,13 @@ LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
+ #endif
+ LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s);
+
++#if LUAJIT_USE_UBSAN
++/* The `NULL` argument with the zero length, like in the case:
++** | luajit -e 'error("x", 3)'
++*/
++static LJ_AINLINE char *lj_buf_wmem(char *p, const void *q, MSize len)
++ __attribute__((no_sanitize("nonnull-attribute")));
++#endif
+ static LJ_AINLINE char *lj_buf_wmem(char *p, const void *q, MSize len)
+ {
+ return (char *)memcpy(p, q, len) + len;
+diff --git a/src/lj_carith.c b/src/lj_carith.c
+index 9bea0a33..046dea4c 100644
+--- a/src/lj_carith.c
++++ b/src/lj_carith.c
+@@ -159,6 +159,11 @@ static int carith_ptr(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
+ }
+
+ /* 64 bit integer arithmetic. */
++#if LUAJIT_USE_UBSAN
++/* See https://github.com/LuaJIT/LuaJIT/issues/928. */
++static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
++ __attribute__((no_sanitize("signed-integer-overflow")));
++#endif
+ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
+ {
+ if (ctype_isnum(ca->ct[0]->info) && ca->ct[0]->size <= 8 &&
+diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
+index ce78505b..bc9d64f3 100644
+--- a/src/lj_opt_fold.c
++++ b/src/lj_opt_fold.c
+@@ -260,6 +260,11 @@ LJFOLDF(kfold_numcomp)
+
+ /* -- Constant folding for 32 bit integers -------------------------------- */
+
++#if LUAJIT_USE_UBSAN
++/* Cdata arithmetic depends on the interger overflow. */
++static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
++ __attribute__((no_sanitize("signed-integer-overflow")));
++#endif
+ static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
+ {
+ switch (op) {
+diff --git a/src/lj_parse.c b/src/lj_parse.c
+index 5a44f8db..bfe044a8 100644
+--- a/src/lj_parse.c
++++ b/src/lj_parse.c
+@@ -934,6 +934,11 @@ static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2)
+ }
+
+ /* Emit unary operator. */
++#if LUAJIT_USE_UBSAN
++/* See https://github.com/LuaJIT/LuaJIT/issues/928. */
++static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
++ __attribute__((no_sanitize("signed-integer-overflow")));
++#endif
+ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
+ {
+ if (op == BC_NOT) {
+diff --git a/src/lj_snap.c b/src/lj_snap.c
+index 6fda08ba..c7f51d7d 100644
+--- a/src/lj_snap.c
++++ b/src/lj_snap.c
+@@ -763,6 +763,13 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex,
+ }
+
+ #if LJ_HASFFI
++# if LUAJIT_USE_UBSAN
++/* See https://github.com/LuaJIT/LuaJIT/issues/1193. */
++static void snap_restoredata(jit_State *J, GCtrace *T, ExitState *ex,
++ SnapNo snapno, BloomFilter rfilt,
++ IRRef ref, void *dst, CTSize sz)
++ __attribute__((no_sanitize("bounds")));
++# endif
+ /* Restore raw data from the trace exit state. */
+ static void snap_restoredata(jit_State *J, GCtrace *T, ExitState *ex,
+ SnapNo snapno, BloomFilter rfilt,
diff --git a/src/lj_str.c b/src/lj_str.c
-index a5282da6..f31172bb 100644
+index cfdaec6f..88f9c765 100644
--- a/src/lj_str.c
+++ b/src/lj_str.c
@@ -13,6 +13,15 @@
#include "lj_char.h"
#include "lj_prng.h"
-
+
+#if LUAJIT_USE_ASAN
+/* These functions may read past a buffer end, that's ok. */
+GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
+#endif /* LUAJIT_USE_ASAN */
+
/* -- String helpers ------------------------------------------------------ */
-
+
/* Ordered compare of strings. Assumes string data is 4-byte aligned. */
+diff --git a/src/lj_strfmt.c b/src/lj_strfmt.c
+index 909255db..ef9bd4f9 100644
+--- a/src/lj_strfmt.c
++++ b/src/lj_strfmt.c
+@@ -99,6 +99,11 @@ retlit:
+ { uint32_t d = (x*(((1<<sh)+sc-1)/sc))>>sh; x -= d*sc; *p++ = (char)('0'+d); }
+
+ /* Write integer to buffer. */
++#if LUAJIT_USE_UBSAN
++/* See https://github.com/LuaJIT/LuaJIT/issues/928. */
++char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k)
++ __attribute__((no_sanitize("signed-integer-overflow")));
++#endif
+ char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k)
+ {
+ uint32_t u = (uint32_t)k;