summaryrefslogtreecommitdiff
path: root/src/script_lua.c
diff options
context:
space:
mode:
authormeir <meir@redis.com>2022-02-06 14:30:15 +0200
committermeir <meir@redis.com>2022-04-27 00:20:54 +0300
commit992f9e23c7ee819ad0dfac0bd6224d8330366960 (patch)
treed5753f6f503293504dc16b7a24925a335c64566f /src/script_lua.c
parent8b33d813a3d47d4daeaaef03b7e42a51f6931f79 (diff)
downloadredis-992f9e23c7ee819ad0dfac0bd6224d8330366960.tar.gz
Move user eval function to be located on Lua registry.
Today, Redis wrap the user Lua code with a Lua function. For example, assuming the user code is: ``` return redis.call('ping') ``` The actual code that would have sent to the Lua interpreter was: ``` f_b3a02c833904802db9c34a3cf1292eee3246df3c() return redis.call('ping') end ``` The wraped code would have been saved on the global dictionary with the following name: `f_<script sha>` (in our example `f_b3a02c833904802db9c34a3cf1292eee3246df3c`). This approach allows one user to easily override the implementation a another user code, example: ``` f_b3a02c833904802db9c34a3cf1292eee3246df3c = function() return 'hacked' end ``` Running the above code will cause `evalsha b3a02c833904802db9c34a3cf1292eee3246df3c 0` to return hacked although it should have returned `pong`. Another disadventage is that Redis basically runs code on the loading (compiling) phase without been aware of it. User can do code injection like this: ``` return 1 end <run code on compling phase> function() return 1 ``` The wraped code will look like this and the entire `<run code on compling phase>` block will run outside of eval or evalsha context: ``` f_<sha>() return 1 end <run code on compling phase> function() return 1 end ```
Diffstat (limited to 'src/script_lua.c')
-rw-r--r--src/script_lua.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/script_lua.c b/src/script_lua.c
index 9a08a7e47..4e1f17649 100644
--- a/src/script_lua.c
+++ b/src/script_lua.c
@@ -1144,7 +1144,7 @@ sds luaGetStringSds(lua_State *lua, int index) {
* On Legacy Lua (eval) we need to check 'w ~= \"main\"' otherwise we will not be able
* to create the global 'function <sha> ()' variable. On Functions Lua engine we do not use
* this trick so it's not needed. */
-void luaEnableGlobalsProtection(lua_State *lua, int is_eval) {
+void luaEnableGlobalsProtection(lua_State *lua) {
char *s[32];
sds code = sdsempty();
int j = 0;
@@ -1157,7 +1157,7 @@ void luaEnableGlobalsProtection(lua_State *lua, int is_eval) {
s[j++]="mt.__newindex = function (t, n, v)\n";
s[j++]=" if dbg.getinfo(2) then\n";
s[j++]=" local w = dbg.getinfo(2, \"S\").what\n";
- s[j++]= is_eval ? " if w ~= \"main\" and w ~= \"C\" then\n" : " if w ~= \"C\" then\n";
+ s[j++]=" if w ~= \"C\" then\n";
s[j++]=" error(\"Script attempted to create global variable '\"..tostring(n)..\"'\", 2)\n";
s[j++]=" end\n";
s[j++]=" end\n";