diff --git a/src/box/call.c b/src/box/call.c index c0bee2ba99ea9ee940661b5febaf9a1f56356620..477e69071019cf11e081ad9eea58dd82abd1efb4 100644 --- a/src/box/call.c +++ b/src/box/call.c @@ -160,9 +160,8 @@ box_run_on_call(enum iproto_type type, const char *expr, int expr_len, trigger_run(&box_on_call, &ctx); } -/** Checks if the current user may execute any global Lua function. */ -static int -access_check_call(const char *name, uint32_t name_len) +int +access_check_lua_call(const char *name, uint32_t name_len) { struct credentials *cr = effective_user(); user_access_t access = PRIV_X | PRIV_U; @@ -182,7 +181,7 @@ access_check_call(const char *name, uint32_t name_len) /** Checks if the current user may execute an arbitrary Lua expression. */ static int -access_check_eval(void) +access_check_lua_eval(void) { struct credentials *cr = effective_user(); user_access_t access = PRIV_X | PRIV_U; @@ -229,7 +228,7 @@ box_process_call(struct call_request *request, struct port *port) goto cleanup; } } else { - if (access_check_call(name, name_len) != 0) { + if (access_check_lua_call(name, name_len) != 0) { rc = -1; goto cleanup; } @@ -249,7 +248,7 @@ box_process_eval(struct call_request *request, struct port *port) { rmean_collect(rmean_box, IPROTO_EVAL, 1); /* Check permissions */ - if (access_check_eval() != 0) + if (access_check_lua_eval() != 0) return -1; struct mp_box_ctx ctx; if (mp_box_ctx_create(&ctx, NULL, request->tuple_formats) != 0) diff --git a/src/box/call.h b/src/box/call.h index 0f8e31842ce1d5dc660354a45ba43d8b5f9022ce..911616772b049fa542b3ceee93a22b2dbaffe6bb 100644 --- a/src/box/call.h +++ b/src/box/call.h @@ -76,6 +76,10 @@ box_process_call(struct call_request *request, struct port *port); int box_process_eval(struct call_request *request, struct port *port); +/** Checks if the current user may execute a global Lua function. */ +int +access_check_lua_call(const char *name, uint32_t name_len); + #if defined(__cplusplus) } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/src/box/func.c b/src/box/func.c index ae3f89c75f17f79b2e6022a2368d39110457daf7..0dfea46254f091301d9ba001f2402a5c3c0a81f3 100644 --- a/src/box/func.c +++ b/src/box/func.c @@ -31,6 +31,7 @@ #include "func.h" #include "fiber.h" #include "assoc.h" +#include "call.h" #include "lua/call.h" #include "diag.h" #include "port.h" @@ -567,6 +568,10 @@ func_access_check(struct func *func) if ((func_access & PRIV_U) != 0 || (func->def->uid != credentials->uid && func_access & ~func->access[credentials->auth_token].effective)) { + if (func->def->language == FUNC_LANGUAGE_LUA && + func->def->body == NULL) + return access_check_lua_call(func->def->name, + func->def->name_len); /* Access violation, report error. */ struct user *user = user_find(credentials->uid); if (user != NULL) { diff --git a/test/box-luatest/gh_8803_exec_priv_test.lua b/test/box-luatest/gh_8803_exec_priv_test.lua index 02e1399d1c587e0fa0c0866e8c85a5b5928ce1c9..fbb9a6067465f584c208b3661e4b71172160d015 100644 --- a/test/box-luatest/gh_8803_exec_priv_test.lua +++ b/test/box-luatest/gh_8803_exec_priv_test.lua @@ -133,6 +133,7 @@ g.before_test('test_lua_call_func', function(cg) language = 'LUA', body = [[function() return true end]], }) + box.schema.func.create('dostring', {language = 'LUA'}) end) end) @@ -141,19 +142,21 @@ g.after_test('test_lua_call_func', function(cg) box.schema.func.drop('c_func') box.schema.func.drop('lua_func') box.schema.func.drop('stored_lua_func') + box.schema.func.drop('dostring') end) end) --- Checks that execute privilege granted on lua_call does not grant access to --- Lua functions from _func. +-- Checks that execute privilege granted on lua_call grants access to +-- Lua functions registered in _func except for built-ins and persistent +-- functions. g.test_lua_call_func = function(cg) local c = cg.conn local errfmt = "Execute access to function '%s' is denied for user 'test'" - local func_list = {'c_func', 'lua_func', 'stored_lua_func'} cg.grant('test', 'execute', 'lua_call') - for _, func in ipairs(func_list) do + for _, func in ipairs({'c_func', 'stored_lua_func', 'dostring'}) do t.assert_error_msg_equals(errfmt:format(func), c.call, c, func) end + t.assert(c:call('lua_func')) end -- Checks that execute privilege granted on lua_call does not grant access