Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
hanoi2005
redis
提交
3e6a4463
R
redis
项目概览
hanoi2005
/
redis
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
3e6a4463
编写于
4月 13, 2012
作者:
A
antirez
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Scripting: globals protection can now be switched on/off.
上级
430602b2
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
83 addition
and
34 deletion
+83
-34
redis.conf
redis.conf
+17
-0
src/config.c
src/config.c
+15
-0
src/redis.c
src/redis.c
+1
-0
src/redis.h
src/redis.h
+3
-0
src/scripting.c
src/scripting.c
+47
-34
未找到文件。
redis.conf
浏览文件 @
3e6a4463
...
...
@@ -401,6 +401,23 @@ auto-aof-rewrite-min-size 64mb
# Set it to 0 or a negative value for unlimited execution without warnings.
lua
-
time
-
limit
5000
# By default variables in a Lua script are global, this means that a correct
# script must declare all the local variables explicitly using the 'local'
# keyword. Lua beginners are known to violate this rule, polluting the global
# namespace, or creating scripts that may fail under certain conditions, for
# this reason by default Redis installs a protection that will raise an error
# every time a script attempts to access a global variable that was not
# explicitly declared via global().
#
# It's worth to note that normal Redis scripts should never use globals, but
# we don't entirely disable the possibility because from time to time crazy
# things in the right hands can be pretty powerful.
#
# Globals protection may result into a minor performance hint, so it is
# possible to disable the feature in production environments using the
# following configuration directive, or at runtime using CONFIG SET.
lua
-
protect
-
globals
yes
################################## SLOW LOG ###################################
# The Redis Slow Log is a system to log queries that exceeded a specified
...
...
src/config.c
浏览文件 @
3e6a4463
...
...
@@ -308,6 +308,10 @@ void loadServerConfigFromString(char *config) {
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"lua-time-limit"
)
&&
argc
==
2
)
{
server
.
lua_time_limit
=
strtoll
(
argv
[
1
],
NULL
,
10
);
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"lua-protect-globals"
)
&&
argc
==
2
)
{
if
((
server
.
lua_protect_globals
=
yesnotoi
(
argv
[
1
]))
==
-
1
)
{
err
=
"argument must be 'yes' or 'no'"
;
goto
loaderr
;
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"slowlog-log-slower-than"
)
&&
argc
==
2
)
{
...
...
@@ -549,6 +553,16 @@ void configSetCommand(redisClient *c) {
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"lua-time-limit"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
||
ll
<
0
)
goto
badfmt
;
server
.
lua_time_limit
=
ll
;
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"lua-protect-globals"
))
{
int
enable
=
yesnotoi
(
o
->
ptr
);
if
(
enable
==
-
1
)
goto
badfmt
;
if
(
enable
==
0
&&
server
.
lua_protect_globals
==
1
)
{
scriptingDisableGlobalsProtection
(
server
.
lua
);
}
else
if
(
enable
&&
server
.
lua_protect_globals
==
0
)
{
scriptingEnableGlobalsProtection
(
server
.
lua
);
}
server
.
lua_protect_globals
=
enable
;
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"slowlog-log-slower-than"
))
{
if
(
getLongLongFromObject
(
o
,
&
ll
)
==
REDIS_ERR
)
goto
badfmt
;
server
.
slowlog_log_slower_than
=
ll
;
...
...
@@ -743,6 +757,7 @@ void configGetCommand(redisClient *c) {
config_get_bool_field
(
"rdbcompression"
,
server
.
rdb_compression
);
config_get_bool_field
(
"rdbchecksum"
,
server
.
rdb_checksum
);
config_get_bool_field
(
"activerehashing"
,
server
.
activerehashing
);
config_get_bool_field
(
"lua-protect-globals"
,
server
.
lua_protect_globals
);
/* Everything we can't handle with macros follows. */
...
...
src/redis.c
浏览文件 @
3e6a4463
...
...
@@ -1067,6 +1067,7 @@ void initServerConfig() {
server
.
lua_time_limit
=
REDIS_LUA_TIME_LIMIT
;
server
.
lua_client
=
NULL
;
server
.
lua_timedout
=
0
;
server
.
lua_protect_globals
=
1
;
updateLRUClock
();
resetServerSaveParams
();
...
...
src/redis.h
浏览文件 @
3e6a4463
...
...
@@ -585,6 +585,7 @@ struct redisServer {
int
lua_timedout
;
/* True if we reached the time limit for script
execution. */
int
lua_kill
;
/* Kill the script if true. */
int
lua_protect_globals
;
/* If true globals must be declared */
/* Assert & bug reportign */
char
*
assert_failed
;
char
*
assert_file
;
...
...
@@ -960,6 +961,8 @@ int *zunionInterGetKeys(struct redisCommand *cmd,robj **argv, int argc, int *num
/* Scripting */
void
scriptingInit
(
void
);
void
scriptingEnableGlobalsProtection
(
lua_State
*
lua
);
void
scriptingDisableGlobalsProtection
(
lua_State
*
lua
);
/* Git SHA1 */
char
*
redisGitSHA1
(
void
);
...
...
src/scripting.c
浏览文件 @
3e6a4463
...
...
@@ -412,45 +412,57 @@ void luaLoadLibraries(lua_State *lua) {
#endif
}
void
scriptingProtectGlobals
(
lua_State
*
lua
)
{
char
*
s
[
26
];
/* This function installs metamethods in the global table _G that prevent
* the creation of globals accidentally.
*
* It should be the last to be called in the scripting engine initialization
* sequence, because it may interact with creation of globals.
* Note that the function is designed to be called multiple times if needed
* without issues, because it is possible to enabled/disable globals protection
* at runtime with CONFIG SET. */
void
scriptingEnableGlobalsProtection
(
lua_State
*
lua
)
{
char
*
s
[
32
];
sds
code
=
sdsempty
();
int
j
;
int
j
=
0
;
/* strict.lua from: http://metalua.luaforge.net/src/lib/strict.lua.html */
s
[
0
]
=
"local mt = getmetatable(_G)
\n
"
;
s
[
1
]
=
"if mt == nil then
\n
"
;
s
[
2
]
=
" mt = {}
\n
"
;
s
[
3
]
=
" setmetatable(_G, mt)
\n
"
;
s
[
4
]
=
"end
\n
"
;
s
[
5
]
=
"__STRICT = true
\n
"
;
s
[
6
]
=
"mt.__declared = {}
\n
"
;
s
[
7
]
=
"mt.__newindex = function (t, n, v)
\n
"
;
s
[
8
]
=
" if __STRICT and not mt.__declared[n] and debug.getinfo(2) then
\n
"
;
s
[
9
]
=
" local w = debug.getinfo(2,
\"
S
\"
).what
\n
"
;
s
[
10
]
=
" if w ~=
\"
main
\"
and w ~=
\"
C
\"
then
\n
"
;
s
[
11
]
=
" error(
\"
assign to undeclared global var '
\"
..n..
\"
'
\"
, 2)
\n
"
;
s
[
12
]
=
" end
\n
"
;
s
[
13
]
=
" mt.__declared[n] = true
\n
"
;
s
[
14
]
=
" end
\n
"
;
s
[
15
]
=
" rawset(t, n, v)
\n
"
;
s
[
16
]
=
"end
\n
"
;
s
[
17
]
=
"mt.__index = function (t, n)
\n
"
;
s
[
18
]
=
" if debug.getinfo(2) and not mt.__declared[n] and debug.getinfo(2,
\"
S
\"
).what ~=
\"
C
\"
then
\n
"
;
s
[
19
]
=
" error(
\"
global var '
\"
..n..
\"
' is not declared
\"
, 2)
\n
"
;
s
[
20
]
=
" end
\n
"
;
s
[
21
]
=
" return rawget(t, n)
\n
"
;
s
[
22
]
=
"end
\n
"
;
s
[
23
]
=
"function global(...)
\n
"
;
s
[
24
]
=
" for _, v in ipairs{...} do mt.__declared[v] = true end
\n
"
;
s
[
25
]
=
"end
\n
"
;
for
(
j
=
0
;
j
<
26
;
j
++
)
code
=
sdscatlen
(
code
,
s
[
j
],
strlen
(
s
[
j
]));
luaL_loadbuffer
(
lua
,
code
,
sdslen
(
code
),
"strict_lua"
);
/* strict.lua from: http://metalua.luaforge.net/src/lib/strict.lua.html.
* Modified to be adapted to Redis. */
s
[
j
++
]
=
"mt = {}
\n
"
;
s
[
j
++
]
=
"setmetatable(_G, mt)
\n
"
;
s
[
j
++
]
=
"mt.declared = {}
\n
"
;
s
[
j
++
]
=
"mt.__newindex = function (t, n, v)
\n
"
;
s
[
j
++
]
=
" if not mt.declared[n] and debug.getinfo(2) then
\n
"
;
s
[
j
++
]
=
" local w = debug.getinfo(2,
\"
S
\"
).what
\n
"
;
s
[
j
++
]
=
" if w ~=
\"
main
\"
and w ~=
\"
C
\"
then
\n
"
;
s
[
j
++
]
=
" error(
\"
assignment to undeclared global variable '
\"
..n..
\"
'
\"
, 2)
\n
"
;
s
[
j
++
]
=
" end
\n
"
;
s
[
j
++
]
=
" mt.declared[n] = true
\n
"
;
s
[
j
++
]
=
" end
\n
"
;
s
[
j
++
]
=
" rawset(t, n, v)
\n
"
;
s
[
j
++
]
=
"end
\n
"
;
s
[
j
++
]
=
"mt.__index = function (t, n)
\n
"
;
s
[
j
++
]
=
" if debug.getinfo(2) and not mt.declared[n] and debug.getinfo(2,
\"
S
\"
).what ~=
\"
C
\"
then
\n
"
;
s
[
j
++
]
=
" error(
\"
global variable '
\"
..n..
\"
' is not declared
\"
, 2)
\n
"
;
s
[
j
++
]
=
" end
\n
"
;
s
[
j
++
]
=
" return rawget(t, n)
\n
"
;
s
[
j
++
]
=
"end
\n
"
;
s
[
j
++
]
=
"function global(...)
\n
"
;
s
[
j
++
]
=
" for _, v in ipairs{...} do mt.declared[v] = true end
\n
"
;
s
[
j
++
]
=
"end
\n
"
;
s
[
j
++
]
=
NULL
;
for
(
j
=
0
;
s
[
j
]
!=
NULL
;
j
++
)
code
=
sdscatlen
(
code
,
s
[
j
],
strlen
(
s
[
j
]));
luaL_loadbuffer
(
lua
,
code
,
sdslen
(
code
),
"enable_strict_lua"
);
lua_pcall
(
lua
,
0
,
0
,
0
);
sdsfree
(
code
);
}
void
scriptingDisableGlobalsProtection
(
lua_State
*
lua
)
{
char
*
s
=
"setmetatable(_G, nil)
\n
"
;
luaL_loadbuffer
(
lua
,
s
,
strlen
(
s
),
"disable_strict_lua"
);
lua_pcall
(
lua
,
0
,
0
,
0
);
}
/* Initialize the scripting environment.
* It is possible to call this function to reset the scripting environment
* assuming that we call scriptingRelease() before.
...
...
@@ -543,7 +555,8 @@ void scriptingInit(void) {
/* Lua beginners ofter don't use "local", this is likely to introduce
* subtle bugs in their code. To prevent problems we protect accesses
* to global variables. */
scriptingProtectGlobals
(
lua
);
if
(
server
.
lua_protect_globals
)
scriptingEnableGlobalsProtection
(
lua
);
server
.
lua
=
lua
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录