EVALSHA_RO and EVAL_RO Commands (#8820)

* EVALSHA_RO and EVAL_RO Commands

Added new readonly versions of EVAL
and EVALSHA.
This commit is contained in:
Raghav Muddur 2021-05-12 21:07:34 -07:00 committed by GitHub
parent e01c92a5ef
commit 31edc22ecc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 0 deletions

View File

@ -603,6 +603,15 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
goto cleanup; goto cleanup;
} }
/* This check is for EVAL_RO, EVALSHA_RO. We want to allow only read only commands */
if ((server.lua_caller->cmd->proc == evalRoCommand ||
server.lua_caller->cmd->proc == evalShaRoCommand) &&
(cmd->flags & CMD_WRITE))
{
luaPushError(lua, "Write commands are not allowed from read-only scripts");
goto cleanup;
}
/* Check the ACLs. */ /* Check the ACLs. */
int acl_errpos; int acl_errpos;
int acl_retval = ACLCheckAllPerm(c,&acl_errpos); int acl_retval = ACLCheckAllPerm(c,&acl_errpos);
@ -1696,6 +1705,10 @@ void evalCommand(client *c) {
evalGenericCommandWithDebugging(c,0); evalGenericCommandWithDebugging(c,0);
} }
void evalRoCommand(client *c) {
evalCommand(c);
}
void evalShaCommand(client *c) { void evalShaCommand(client *c) {
if (sdslen(c->argv[1]->ptr) != 40) { if (sdslen(c->argv[1]->ptr) != 40) {
/* We know that a match is not possible if the provided SHA is /* We know that a match is not possible if the provided SHA is
@ -1713,6 +1726,10 @@ void evalShaCommand(client *c) {
} }
} }
void evalShaRoCommand(client *c) {
evalShaCommand(c);
}
void scriptCommand(client *c) { void scriptCommand(client *c) {
if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) { if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) {
const char *help[] = { const char *help[] = {

View File

@ -910,10 +910,18 @@ struct redisCommand redisCommandTable[] = {
"no-script may-replicate @scripting", "no-script may-replicate @scripting",
0,evalGetKeys,0,0,0,0,0,0}, 0,evalGetKeys,0,0,0,0,0,0},
{"eval_ro",evalRoCommand,-3,
"no-script @scripting",
0,evalGetKeys,0,0,0,0,0,0},
{"evalsha",evalShaCommand,-3, {"evalsha",evalShaCommand,-3,
"no-script may-replicate @scripting", "no-script may-replicate @scripting",
0,evalGetKeys,0,0,0,0,0,0}, 0,evalGetKeys,0,0,0,0,0,0},
{"evalsha_ro",evalShaRoCommand,-3,
"no-script @scripting",
0,evalGetKeys,0,0,0,0,0,0},
{"slowlog",slowlogCommand,-2, {"slowlog",slowlogCommand,-2,
"admin random ok-loading ok-stale", "admin random ok-loading ok-stale",
0,NULL,0,0,0,0,0,0}, 0,NULL,0,0,0,0,0,0},

View File

@ -2644,7 +2644,9 @@ void memoryCommand(client *c);
void clientCommand(client *c); void clientCommand(client *c);
void helloCommand(client *c); void helloCommand(client *c);
void evalCommand(client *c); void evalCommand(client *c);
void evalRoCommand(client *c);
void evalShaCommand(client *c); void evalShaCommand(client *c);
void evalShaRoCommand(client *c);
void scriptCommand(client *c); void scriptCommand(client *c);
void timeCommand(client *c); void timeCommand(client *c);
void bitopCommand(client *c); void bitopCommand(client *c);

View File

@ -320,6 +320,17 @@ start_server {tags {"scripting"}} {
r eval {return 'hello' --trailing comment} 0 r eval {return 'hello' --trailing comment} 0
} {hello} } {hello}
test {EVAL_RO - Successful case} {
r set foo bar
assert_equal bar [r eval_ro {return redis.call('get', KEYS[1]);} 1 foo]
}
test {EVAL_RO - Cannot run write commands} {
r set foo bar
catch {r eval_ro {redis.call('del', KEYS[1]);} 1 foo} e
set e
} {*Write commands are not allowed from read-only scripts*}
test {SCRIPTING FLUSH - is able to clear the scripts cache?} { test {SCRIPTING FLUSH - is able to clear the scripts cache?} {
r set mykey myval r set mykey myval
set v [r evalsha fd758d1589d044dd850a6f05d52f2eefd27f033f 1 mykey] set v [r evalsha fd758d1589d044dd850a6f05d52f2eefd27f033f 1 mykey]