Skip to content

Commit c2a4c40

Browse files
committed
Patches by burii
1 parent a7c2eca commit c2a4c40

File tree

3 files changed

+228
-0
lines changed

3 files changed

+228
-0
lines changed

Dockerfile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Use the latest Ubuntu LTS release as the base image
2+
FROM ubuntu:latest
3+
4+
# Set environment variables (optional)
5+
ENV DEBIAN_FRONTEND=noninteractive
6+
7+
# Update package lists and install any necessary packages
8+
RUN apt-get update
9+
RUN apt-get install -y curl
10+
RUN apt-get install -y bash
11+
RUN apt-get install -y vim
12+
RUN apt-get install -y make
13+
RUN apt-get install -y cmake
14+
RUN apt-get install -y clang
15+
RUN apt-get install -y git
16+
RUN apt-get install -y libicu-dev
17+
RUN apt-get install -y libreadline8 libreadline-dev
18+
RUN apt-get install -y luarocks
19+
RUN apt-get install -y build-essential
20+
RUN apt-get install -y zlib1g zlib1g-dev
21+
RUN apt-get install -y openssl libssl-dev
22+
RUN apt-get install -y liblzma-dev
23+
RUN apt-get install -y screen
24+
25+
RUN git clone https://github.com/tarantool/tarantool.git
26+
COPY conv.patch /conv.patch
27+
COPY fuzzer.patch /fuzzer.patch
28+
WORKDIR /tarantool
29+
RUN CC=clang CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_FUZZER=ON -DENABLE_BACKTRACE=ON -DLUAJIT_ENABLE_GC64=ON .
30+
WORKDIR /tarantool/third_party/luajit
31+
RUN git apply /conv.patch
32+
WORKDIR /tarantool
33+
RUN git apply /fuzzer.patch
34+
RUN make luaL_loadbuffer_fuzzer -j4
35+
36+
# Copy application files (if any)
37+
COPY .screenrc /.screenrc
38+
39+
# Define the command to run when the container starts
40+
CMD ["bash"]

conv.patch

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
diff --git a/src/lj_record.c b/src/lj_record.c
2+
index 1dd22dac..e930eba6 100644
3+
--- a/src/lj_record.c
4+
+++ b/src/lj_record.c
5+
@@ -443,6 +448,19 @@ static void rec_for_check(jit_State *J, IRType t, int dir,
6+
}
7+
}
8+
9+
+/* Convert IR to the target number type. Used for loop indexes narrowing. */
10+
+static TRef irconv_numtype(jit_State *J, TRef tr, IRType t)
11+
+{
12+
+ if (t == IRT_INT) {
13+
+ if (!tref_isinteger(tr))
14+
+ return emitir(IRTGI(IR_CONV), tr, IRCONV_INT_NUM|IRCONV_CHECK);
15+
+ } else {
16+
+ if (!tref_isnum(tr))
17+
+ return emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
18+
+ }
19+
+ return tr;
20+
+}
21+
+
22+
/* Record a FORL instruction. */
23+
static void rec_for_loop(jit_State *J, const BCIns *fori, ScEvEntry *scev,
24+
int init)
25+
@@ -454,8 +472,8 @@ static void rec_for_loop(jit_State *J, const BCIns *fori, ScEvEntry *scev,
26+
(init || LJ_DUALNUM) ? lj_opt_narrow_forl(J, tv) : IRT_NUM;
27+
int mode = IRSLOAD_INHERIT +
28+
((!LJ_DUALNUM || tvisint(tv) == (t == IRT_INT)) ? IRSLOAD_READONLY : 0);
29+
- TRef stop = fori_arg(J, fori, ra+FORL_STOP, t, mode);
30+
- TRef step = fori_arg(J, fori, ra+FORL_STEP, t, mode);
31+
+ TRef stop = irconv_numtype(J, fori_arg(J, fori, ra+FORL_STOP, t, mode), t);
32+
+ TRef step = irconv_numtype(J, fori_arg(J, fori, ra+FORL_STEP, t, mode), t);
33+
int tc, dir = rec_for_direction(&tv[FORL_STEP]);
34+
lj_assertJ(bc_op(*fori) == BC_FORI || bc_op(*fori) == BC_JFORI,
35+
"bad bytecode %d instead of FORI/JFORI", bc_op(*fori));
36+
@@ -517,13 +535,7 @@ static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl)
37+
lj_assertJ(tref_isnumber_str(tr[i]), "bad FORI argument type");
38+
if (tref_isstr(tr[i]))
39+
tr[i] = emitir(IRTG(IR_STRTO, IRT_NUM), tr[i], 0);
40+
- if (t == IRT_INT) {
41+
- if (!tref_isinteger(tr[i]))
42+
- tr[i] = emitir(IRTGI(IR_CONV), tr[i], IRCONV_INT_NUM|IRCONV_CHECK);
43+
- } else {
44+
- if (!tref_isnum(tr[i]))
45+
- tr[i] = emitir(IRTN(IR_CONV), tr[i], IRCONV_NUM_INT);
46+
- }
47+
+ tr[i] = irconv_numtype(J, tr[i], t);
48+
}
49+
tr[FORL_EXT] = tr[FORL_IDX];
50+
stop = tr[FORL_STOP];

fuzzer.patch

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
diff --git a/test/fuzz/luaL_loadbuffer/luaL_loadbuffer_fuzzer.cc b/test/fuzz/luaL_loadbuffer/luaL_loadbuffer_fuzzer.cc
2+
index 05fb39ceb0..24af9ae216 100644
3+
--- a/test/fuzz/luaL_loadbuffer/luaL_loadbuffer_fuzzer.cc
4+
+++ b/test/fuzz/luaL_loadbuffer/luaL_loadbuffer_fuzzer.cc
5+
@@ -21,6 +21,74 @@ extern "C"
6+
<< " (" << (val) * 100 / (total) << "%)" \
7+
<< std::endl
8+
9+
+#define LUA_MEMORY_LIMIT_DEFAULT (2ULL * 1024 * 1024 * 1024)
10+
+
11+
+/**
12+
+ * Default allocator function which is wrapped into a new one
13+
+ * with the Lua memory limit checker.
14+
+ */
15+
+static lua_Alloc orig_alloc;
16+
+/**
17+
+ * Memory limit for LuaJIT.
18+
+ */
19+
+static size_t memory_limit = LUA_MEMORY_LIMIT_DEFAULT;
20+
+/**
21+
+ * Amount of memory used by LuaJIT.
22+
+ */
23+
+static size_t used;
24+
+
25+
+/**
26+
+ * Lua custom memory allocation function. It extends the original
27+
+ * one with a memory counter and a limit check.
28+
+ */
29+
+static void *
30+
+alloc_with_limit(void *ud, void *ptr, size_t osize, size_t nsize)
31+
+{
32+
+ size_t new_used = used + nsize - osize;
33+
+ if (new_used > memory_limit) {
34+
+ /*
35+
+ * Returning NULL results in the "not enough
36+
+ * memory" error.
37+
+ */
38+
+ return NULL;
39+
+ }
40+
+
41+
+ void *result = orig_alloc(ud, ptr, osize, nsize);
42+
+
43+
+ if (result != NULL || nsize == 0)
44+
+ used = new_used;
45+
+
46+
+ /*
47+
+ * Result may be NULL, in this case "not enough memory"
48+
+ * is raised.
49+
+ */
50+
+ return result;
51+
+}
52+
+
53+
+static size_t
54+
+getgctotal(struct lua_State *L)
55+
+{
56+
+ return (lua_getgccount(L) * 1024ULL) + lua_gc(L, LUA_GCCOUNTB, 0);
57+
+}
58+
+
59+
+static void
60+
+lua_initalloc(struct lua_State *L)
61+
+{
62+
+ assert(L != NULL);
63+
+
64+
+ used = getgctotal(L);
65+
+
66+
+ void *orig_ud;
67+
+ orig_alloc = lua_getallocf(L, &orig_ud);
68+
+
69+
+ assert(orig_alloc != NULL);
70+
+
71+
+ if (::getenv("LUA_MEMMAX"))
72+
+ memory_limit = std::stoi(::getenv("LUA_MEMMAX"));
73+
+
74+
+ lua_setallocf(L, alloc_with_limit, orig_ud);
75+
+}
76+
+
77+
struct metrics {
78+
size_t total_num;
79+
size_t total_num_with_errors;
80+
@@ -111,6 +179,7 @@ DEFINE_PROTO_FUZZER(const lua_grammar::Block &message)
81+
if (!L)
82+
return;
83+
84+
+ lua_initalloc(L);
85+
std::string code = luajit_fuzzer::MainBlockToString(message);
86+
87+
if (::getenv("LPM_DUMP_NATIVE_INPUT") && code.size() != 0) {
88+
@@ -130,6 +199,8 @@ DEFINE_PROTO_FUZZER(const lua_grammar::Block &message)
89+
90+
if (luaL_loadbuffer(L, code.c_str(), code.size(), "fuzz") != LUA_OK) {
91+
report_error(L, "luaL_loadbuffer()");
92+
+
93+
+ std::cout << code << std::endl;
94+
goto end;
95+
}
96+
97+
@@ -140,8 +211,9 @@ DEFINE_PROTO_FUZZER(const lua_grammar::Block &message)
98+
* needed to describe Lua semantics for more interesting
99+
* results and fuzzer tests.
100+
*/
101+
- if (lua_pcall(L, 0, 0, 0) != LUA_OK)
102+
+ if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
103+
report_error(L, "lua_pcall()");
104+
+ }
105+
106+
end:
107+
metrics.total_num++;
108+
diff --git a/test/fuzz/luaL_loadbuffer/serializer.cc b/test/fuzz/luaL_loadbuffer/serializer.cc
109+
index b029ddb8ce..72074dc941 100644
110+
--- a/test/fuzz/luaL_loadbuffer/serializer.cc
111+
+++ b/test/fuzz/luaL_loadbuffer/serializer.cc
112+
@@ -647,7 +647,7 @@ NESTED_PROTO_TOSTRING(Args, args, FunctionCall)
113+
case ArgsType::kTableconstructor:
114+
return TableConstructorToString(args.tableconstructor());
115+
case ArgsType::kStr:
116+
- return "'" + ConvertToStringDefault(args.str()) + "'";
117+
+ return "'" + ConvertToStringDefault(args.str(), true) + "'";
118+
default:
119+
/* For more variability. */
120+
return TableConstructorToString(args.tableconstructor());
121+
@@ -982,7 +982,7 @@ PROTO_TOSTRING(Expression, expr)
122+
return std::to_string(number);
123+
}
124+
case ExprType::kStr:
125+
- return "'" + ConvertToStringDefault(expr.str()) + "'";
126+
+ return "'" + ConvertToStringDefault(expr.str(), true) + "'";
127+
case ExprType::kEllipsis:
128+
if (GetContext().vararg_is_possible()) {
129+
return " ... ";
130+
@@ -1004,7 +1004,7 @@ PROTO_TOSTRING(Expression, expr)
131+
* Arbitrary choice.
132+
* TODO: Choose "more interesting" defaults.
133+
*/
134+
- return "'" + ConvertToStringDefault(expr.str()) + "'";
135+
+ return "'" + ConvertToStringDefault(expr.str(), true) + "'";
136+
}
137+
}
138+

0 commit comments

Comments
 (0)