From 0736b5b08f61be9ff9f62f885912f934c7df5aed Mon Sep 17 00:00:00 2001 From: DavidKorczynski Date: Mon, 30 Nov 2020 19:48:27 +0000 Subject: [Lua]initial integration. (#4653) --- projects/lua/Dockerfile | 22 +++++++ projects/lua/build.sh | 26 ++++++++ projects/lua/fuzz_lua.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ projects/lua/project.yaml | 6 ++ 4 files changed, 208 insertions(+) create mode 100644 projects/lua/Dockerfile create mode 100755 projects/lua/build.sh create mode 100644 projects/lua/fuzz_lua.c create mode 100644 projects/lua/project.yaml (limited to 'projects/lua') diff --git a/projects/lua/Dockerfile b/projects/lua/Dockerfile new file mode 100644 index 00000000..054ce66c --- /dev/null +++ b/projects/lua/Dockerfile @@ -0,0 +1,22 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder +RUN apt-get update && apt-get install -y libreadline-dev +RUN git clone https://github.com/lua/lua +WORKDIR $SRC +COPY build.sh $SRC/ +COPY fuzz_lua.c $SRC/ diff --git a/projects/lua/build.sh b/projects/lua/build.sh new file mode 100755 index 00000000..7c65d0d3 --- /dev/null +++ b/projects/lua/build.sh @@ -0,0 +1,26 @@ +#!/bin/bash -eu +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +sed "s/CFLAGS=/CFLAGS+=/g" -i $SRC/lua/makefile +sed "s/MYLDFLAGS=/MYLDFLAGS=${CFLAGS} /g" -i $SRC/lua/makefile +sed "s/CC= gcc/CC= ${CC}/g" -i $SRC/lua/makefile + +cd $SRC/lua +make +cp ../fuzz_lua.c . +$CC $CFLAGS -c fuzz_lua.c -o fuzz_lua.o +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE fuzz_lua.o -o $OUT/fuzz_lua ./liblua.a diff --git a/projects/lua/fuzz_lua.c b/projects/lua/fuzz_lua.c new file mode 100644 index 00000000..2acaf2c4 --- /dev/null +++ b/projects/lua/fuzz_lua.c @@ -0,0 +1,154 @@ +/* Copyright 2020 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#define lua_c + +#include "lprefix.h" + + +#include +#include +#include +#include + +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#if !defined(LUA_PROGNAME) +#define LUA_PROGNAME "lua" +#endif + +#if !defined(LUA_INIT_VAR) +#define LUA_INIT_VAR "LUA_INIT" +#endif + +#define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX + + +static lua_State *globalL = NULL; + +static const char *progname = LUA_PROGNAME; + + +/* +** Hook set by signal function to stop the interpreter. +*/ +static void lstop (lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); /* reset hook */ + luaL_error(L, "interrupted!"); +} + + +/* +** Function to be called at a C signal. Because a C signal cannot +** just change a Lua state (as there is no proper synchronization), +** this function only sets a hook that, when called, will stop the +** interpreter. +*/ +static void laction (int i) { + int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT; + signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */ + lua_sethook(globalL, lstop, flag, 1); +} + + + +/* +** Prints an error message, adding the program name in front of it +** (if present) +*/ +static void l_message (const char *pname, const char *msg) { + if (pname) lua_writestringerror("%s: ", pname); + lua_writestringerror("%s\n", msg); +} + + +/* +** Check whether 'status' is not OK and, if so, prints the error +** message on the top of the stack. It assumes that the error object +** is a string, as it was either generated by Lua or by 'msghandler'. +*/ +static int report (lua_State *L, int status) { + if (status != LUA_OK) { + const char *msg = lua_tostring(L, -1); + l_message(progname, msg); + lua_pop(L, 1); /* remove message */ + } + return status; +} + +/* +** Message handler used to run all chunks +*/ +static int msghandler (lua_State *L) { + const char *msg = lua_tostring(L, 1); + if (msg == NULL) { /* is error object not a string? */ + if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */ + lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */ + return 1; /* that is the message */ + else + msg = lua_pushfstring(L, "(error object is a %s value)", + luaL_typename(L, 1)); + } + luaL_traceback(L, L, msg, 1); /* append a standard traceback */ + return 1; /* return the traceback */ +} + + +/* +** Interface to 'lua_pcall', which sets appropriate message function +** and C-signal handler. Used to run all chunks. +*/ +static int docall (lua_State *L, int narg, int nres) { + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, msghandler); /* push message handler */ + lua_insert(L, base); /* put it under function and args */ + globalL = L; /* to be available to 'laction' */ + signal(SIGINT, laction); /* set C-signal handler */ + status = lua_pcall(L, narg, nres, base); + signal(SIGINT, SIG_DFL); /* reset C-signal handler */ + lua_remove(L, base); /* remove message handler from the stack */ + return status; +} + + +static int dochunk (lua_State *L, int status) { + if (status == LUA_OK) status = docall(L, 0, 0); + return report(L, status); +} + + +/* mark in error messages for incomplete statements */ +#define EOFMARK "" +#define marklen (sizeof(EOFMARK)/sizeof(char) - 1) + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + lua_State *L = luaL_newstate(); + if (L == NULL) { + return 0; + } + dochunk(L, luaL_loadbufferx(L, data, size, "test", "t")); + + lua_close(L); + return 0; +} diff --git a/projects/lua/project.yaml b/projects/lua/project.yaml new file mode 100644 index 00000000..96dade78 --- /dev/null +++ b/projects/lua/project.yaml @@ -0,0 +1,6 @@ +homepage: "https://github.com/lua/lua" +language: c +primary_contact: "roberto@inf.puc-rio.br" +auto_ccs: + - "fuzz@llua.org" + - "david@adalogics.com" -- cgit v1.2.3