<HTML><BODY><div>Hi Oleg, LGTM, please proceed to Kirill to push.<br><br> <blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">Вторник, 24 марта 2020, 11:12 +03:00 от Sergey Bronnikov <sergeyb@tarantool.org>:<br> <div id=""><div class="js-helper js-readmsg-msg"><style type="text/css"></style><div><div id="style_15850375562104881548_BODY">LGTM.<br><br>On 13:00 Mon 23 Mar , Oleg Piskunov wrote:<div class="mail-quote-collapse">><br>> Splitted single access_escalation.test.lua to a set of small independent tests.<br>><br>> Github: <a href="https://github.com/tarantool/tarantool/tree/opiskunov/access_escal_test_split" target="_blank">https://github.com/tarantool/tarantool/tree/opiskunov/access_escal_test_split</a><br>><br>> ---<br>> test/box/access_de_escalation.result | 90 ++++++++++++++++++<br>> test/box/access_de_escalation.test.lua | 50 ++++++++++<br>> test/box/access_escalation.result | 144 -----------------------------<br>> test/box/access_escalation.test.lua | 89 ------------------<br>> test/box/access_escalation_gh-617.result | 70 ++++++++++++++<br>> test/box/access_escalation_gh-617.test.lua | 48 ++++++++++<br>> 6 files changed, 258 insertions(+), 233 deletions(-)<br>> create mode 100644 test/box/access_de_escalation.result<br>> create mode 100644 test/box/access_de_escalation.test.lua<br>> delete mode 100644 test/box/access_escalation.result<br>> delete mode 100644 test/box/access_escalation.test.lua<br>> create mode 100644 test/box/access_escalation_gh-617.result<br>> create mode 100644 test/box/access_escalation_gh-617.test.lua<br>><br>> diff --git a/test/box/access_de_escalation.result b/test/box/access_de_escalation.result<br>> new file mode 100644<br>> index 0000000..799ed1c<br>> --- /dev/null<br>> +++ b/test/box/access_de_escalation.result<br>> @@ -0,0 +1,90 @@<br>> +fiber = require('fiber')<br>> +---<br>> +...<br>> +net = require('net.box')<br>> +---<br>> +...<br>> +os = require('os')<br>> +---<br>> +...<br>> +-- Test for privilege de-escalation<br>> +-- --------------------------------<br>> +--<br>> +-- * create a setuid function which runs under a deprived user<br>> +-- * invoke the function, let it sleep<br>> +-- * invoke a function which should have privileges<br>> +--<br>> +-- define functions<br>> +channel = fiber.channel(1)<br>> +---<br>> +...<br>> +function setuid() channel:get() end<br>> +---<br>> +...<br>> +function escalation() return box.space._space:get{box.schema.SPACE_ID} ~= nil end<br>> +---<br>> +...<br>> +-- create a deprived user<br>> +box.schema.user.create('underprivileged')<br>> +---<br>> +...<br>> +box.schema.user.grant('underprivileged', 'read,write', 'space', '_func')<br>> +---<br>> +...<br>> +box.schema.user.grant('underprivileged', 'create', 'function')<br>> +---<br>> +...<br>> +box.session.su('underprivileged')<br>> +---<br>> +...<br>> +box.schema.func.create('setuid', {setuid=true})<br>> +---<br>> +...<br>> +box.session.su('admin')<br>> +---<br>> +...<br>> +--<br>> +-- create a deprived function<br>> +--<br>> +box.schema.func.create('escalation')<br>> +---<br>> +...<br>> +box.schema.user.grant('guest', 'execute', 'function', 'setuid')<br>> +---<br>> +...<br>> +box.schema.user.grant('guest', 'execute', 'function', 'escalation')<br>> +---<br>> +...<br>> +box.schema.user.grant('guest', 'read', 'space', '_space')<br>> +---<br>> +...<br>> +connection = net:connect(os.getenv("LISTEN"))<br>> +---<br>> +...<br>> +background = fiber.create(function() connection:call("setuid") end)<br>> +---<br>> +...<br>> +connection:call("escalation")<br>> +---<br>> +- true<br>> +...<br>> +channel:put(true)<br>> +---<br>> +- true<br>> +...<br>> +-- tear down<br>> +box.schema.func.drop('setuid')<br>> +---<br>> +...<br>> +box.schema.user.drop('underprivileged')<br>> +---<br>> +...<br>> +box.schema.func.drop('escalation')<br>> +---<br>> +...<br>> +box.schema.user.revoke('guest', 'read', 'space', '_space')<br>> +---<br>> +...<br>> +connection:close()<br>> +---<br>> +...<br>> diff --git a/test/box/access_de_escalation.test.lua b/test/box/access_de_escalation.test.lua<br>> new file mode 100644<br>> index 0000000..e621fd0<br>> --- /dev/null<br>> +++ b/test/box/access_de_escalation.test.lua<br>> @@ -0,0 +1,50 @@<br>> +fiber = require('fiber')<br>> +net = require('net.box')<br>> +os = require('os')<br>> +<br>> +-- Test for privilege de-escalation<br>> +-- --------------------------------<br>> +<br>> +--<br>> +-- * create a setuid function which runs under a deprived user<br>> +-- * invoke the function, let it sleep<br>> +-- * invoke a function which should have privileges<br>> +--<br>> +<br>> +-- define functions<br>> +<br>> +channel = fiber.channel(1)<br>> +function setuid() channel:get() end<br>> +<br>> +function escalation() return box.space._space:get{box.schema.SPACE_ID} ~= nil end<br>> +<br>> +-- create a deprived user<br>> +<br>> +box.schema.user.create('underprivileged')<br>> +box.schema.user.grant('underprivileged', 'read,write', 'space', '_func')<br>> +box.schema.user.grant('underprivileged', 'create', 'function')<br>> +box.session.su('underprivileged')<br>> +box.schema.func.create('setuid', {setuid=true})<br>> +box.session.su('admin')<br>> +--<br>> +-- create a deprived function<br>> +--<br>> +<br>> +box.schema.func.create('escalation')<br>> +box.schema.user.grant('guest', 'execute', 'function', 'setuid')<br>> +box.schema.user.grant('guest', 'execute', 'function', 'escalation')<br>> +box.schema.user.grant('guest', 'read', 'space', '_space')<br>> +<br>> +connection = net:connect(os.getenv("LISTEN"))<br>> +<br>> +background = fiber.create(function() connection:call("setuid") end)<br>> +connection:call("escalation")<br>> +channel:put(true)<br>> +<br>> +-- tear down<br>> +<br>> +box.schema.func.drop('setuid')<br>> +box.schema.user.drop('underprivileged')<br>> +box.schema.func.drop('escalation')<br>> +box.schema.user.revoke('guest', 'read', 'space', '_space')<br>> +connection:close()<br>> diff --git a/test/box/access_escalation.result b/test/box/access_escalation.result<br>> deleted file mode 100644<br>> index df8a947..0000000<br>> --- a/test/box/access_escalation.result<br>> +++ /dev/null<br>> @@ -1,144 +0,0 @@<br>> -fiber = require('fiber')<br>> ----<br>> -...<br>> -net = require('net.box')<br>> ----<br>> -...<br>> -log = require('log')<br>> ----<br>> -...<br>> -json = require('json')<br>> ----<br>> -...<br>> -os = require('os')<br>> ----<br>> -...<br>> --- gh-617: guest access denied because of setuid<br>> --- function invocation.<br>> --- Test for privilege escalation<br>> --- -----------------------------<br>> --- * create a setuid function which changes effective id<br>> --- to superuser<br>> --- * invoke it via the binary protocol<br>> --- * while the function is running, invoke a non-setuid function<br>> --- which reads a system space.<br>> ---<br>> --- The invoked function should get "Access denied" error,<br>> --- there should be no privilege escalation.<br>> --- define functions<br>> -channel = fiber.channel(1)<br>> ----<br>> -...<br>> -function setuid() channel:get() end<br>> ----<br>> -...<br>> -function escalation() return box.space._space:get{box.schema.SPACE_ID} ~= nil end<br>> ----<br>> -...<br>> --- set up grants<br>> -box.schema.func.create('setuid', {setuid=true})<br>> ----<br>> -...<br>> -box.schema.func.create('escalation')<br>> ----<br>> -...<br>> -box.schema.user.grant('guest', 'execute', 'function', 'setuid')<br>> ----<br>> -...<br>> -box.schema.user.grant('guest', 'execute', 'function', 'escalation')<br>> ----<br>> -...<br>> -connection = net:connect(os.getenv("LISTEN"))<br>> ----<br>> -...<br>> -background = fiber.create(function() connection:call("setuid") end)<br>> ----<br>> -...<br>> -connection:call("escalation")<br>> ----<br>> -- error: Read access to space '_space' is denied for user 'guest'<br>> -...<br>> -channel:put(true)<br>> ----<br>> -- true<br>> -...<br>> ---<br>> --- tear down the functions; the grants are dropped recursively<br>> ---<br>> -box.schema.func.drop('setuid')<br>> ----<br>> -...<br>> -box.schema.func.drop('escalation')<br>> ----<br>> -...<br>> -connection:close()<br>> ----<br>> -...<br>> --- Test for privilege de-escalation<br>> --- --------------------------------<br>> ---<br>> --- * create a setuid function which runs under a deprived user<br>> --- * invoke the function, let it sleep<br>> --- * invoke a function which should have privileges<br>> ---<br>> --- create a deprived user<br>> -box.schema.user.create('underprivileged')<br>> ----<br>> -...<br>> -box.schema.user.grant('underprivileged', 'read,write', 'space', '_func')<br>> ----<br>> -...<br>> -box.schema.user.grant('underprivileged', 'create', 'function')<br>> ----<br>> -...<br>> -box.session.su('underprivileged')<br>> ----<br>> -...<br>> -box.schema.func.create('setuid', {setuid=true})<br>> ----<br>> -...<br>> -box.session.su('admin')<br>> ----<br>> -...<br>> ---<br>> --- create a deprived function<br>> ---<br>> -box.schema.func.create('escalation')<br>> ----<br>> -...<br>> -box.schema.user.grant('guest', 'execute', 'function', 'setuid')<br>> ----<br>> -...<br>> -box.schema.user.grant('guest', 'execute', 'function', 'escalation')<br>> ----<br>> -...<br>> -box.schema.user.grant('guest', 'read', 'space', '_space')<br>> ----<br>> -...<br>> -connection = net:connect(os.getenv("LISTEN"))<br>> ----<br>> -...<br>> -background = fiber.create(function() connection:call("setuid") end)<br>> ----<br>> -...<br>> -connection:call("escalation")<br>> ----<br>> -- true<br>> -...<br>> -channel:put(true)<br>> ----<br>> -- true<br>> -...<br>> --- tear down<br>> -box.schema.user.drop('underprivileged')<br>> ----<br>> -...<br>> -box.schema.func.drop('escalation')<br>> ----<br>> -...<br>> -box.schema.user.revoke('guest', 'read', 'space', '_space')<br>> ----<br>> -...<br>> -connection:close()<br>> ----<br>> -...<br>> diff --git a/test/box/access_escalation.test.lua b/test/box/access_escalation.test.lua<br>> deleted file mode 100644<br>> index 9f35f21..0000000<br>> --- a/test/box/access_escalation.test.lua<br>> +++ /dev/null<br>> @@ -1,89 +0,0 @@<br>> -fiber = require('fiber')<br>> -net = require('net.box')<br>> -log = require('log')<br>> -json = require('json')<br>> -os = require('os')<br>> -<br>> --- gh-617: guest access denied because of setuid<br>> --- function invocation.<br>> -<br>> --- Test for privilege escalation<br>> --- -----------------------------<br>> --- * create a setuid function which changes effective id<br>> --- to superuser<br>> --- * invoke it via the binary protocol<br>> --- * while the function is running, invoke a non-setuid function<br>> --- which reads a system space.<br>> ---<br>> --- The invoked function should get "Access denied" error,<br>> --- there should be no privilege escalation.<br>> -<br>> --- define functions<br>> -<br>> -channel = fiber.channel(1)<br>> -function setuid() channel:get() end<br>> -<br>> -function escalation() return box.space._space:get{box.schema.SPACE_ID} ~= nil end<br>> -<br>> --- set up grants<br>> -<br>> -box.schema.func.create('setuid', {setuid=true})<br>> -box.schema.func.create('escalation')<br>> -<br>> -box.schema.user.grant('guest', 'execute', 'function', 'setuid')<br>> -box.schema.user.grant('guest', 'execute', 'function', 'escalation')<br>> -<br>> -<br>> -connection = net:connect(os.getenv("LISTEN"))<br>> -<br>> -background = fiber.create(function() connection:call("setuid") end)<br>> -connection:call("escalation")<br>> -channel:put(true)<br>> -<br>> ---<br>> --- tear down the functions; the grants are dropped recursively<br>> ---<br>> -<br>> -box.schema.func.drop('setuid')<br>> -box.schema.func.drop('escalation')<br>> -<br>> -connection:close()<br>> -<br>> --- Test for privilege de-escalation<br>> --- --------------------------------<br>> -<br>> ---<br>> --- * create a setuid function which runs under a deprived user<br>> --- * invoke the function, let it sleep<br>> --- * invoke a function which should have privileges<br>> ---<br>> -<br>> --- create a deprived user<br>> -<br>> -box.schema.user.create('underprivileged')<br>> -box.schema.user.grant('underprivileged', 'read,write', 'space', '_func')<br>> -box.schema.user.grant('underprivileged', 'create', 'function')<br>> -box.session.su('underprivileged')<br>> -box.schema.func.create('setuid', {setuid=true})<br>> -box.session.su('admin')<br>> ---<br>> --- create a deprived function<br>> ---<br>> -<br>> -box.schema.func.create('escalation')<br>> -box.schema.user.grant('guest', 'execute', 'function', 'setuid')<br>> -box.schema.user.grant('guest', 'execute', 'function', 'escalation')<br>> -box.schema.user.grant('guest', 'read', 'space', '_space')<br>> -<br>> -connection = net:connect(os.getenv("LISTEN"))<br>> -<br>> -background = fiber.create(function() connection:call("setuid") end)<br>> -connection:call("escalation")<br>> -channel:put(true)<br>> -<br>> --- tear down<br>> -<br>> -box.schema.user.drop('underprivileged')<br>> -box.schema.func.drop('escalation')<br>> -box.schema.user.revoke('guest', 'read', 'space', '_space')<br>> -connection:close()<br>> diff --git a/test/box/access_escalation_gh-617.result b/test/box/access_escalation_gh-617.result<br>> new file mode 100644<br>> index 0000000..bf9c93f<br>> --- /dev/null<br>> +++ b/test/box/access_escalation_gh-617.result<br>> @@ -0,0 +1,70 @@<br>> +fiber = require('fiber')<br>> +---<br>> +...<br>> +net = require('net.box')<br>> +---<br>> +...<br>> +os = require('os')<br>> +---<br>> +...<br>> +-- gh-617: guest access denied because of setuid<br>> +-- function invocation.<br>> +-- Test for privilege escalation<br>> +-- -----------------------------<br>> +-- * create a setuid function which changes effective id<br>> +-- to superuser<br>> +-- * invoke it via the binary protocol<br>> +-- * while the function is running, invoke a non-setuid function<br>> +-- which reads a system space.<br>> +--<br>> +-- The invoked function should get "Access denied" error,<br>> +-- there should be no privilege escalation.<br>> +-- define functions<br>> +channel = fiber.channel(1)<br>> +---<br>> +...<br>> +function setuid() channel:get() end<br>> +---<br>> +...<br>> +function escalation() return box.space._space:get{box.schema.SPACE_ID} ~= nil end<br>> +---<br>> +...<br>> +-- set up grants<br>> +box.schema.func.create('setuid', {setuid=true})<br>> +---<br>> +...<br>> +box.schema.func.create('escalation')<br>> +---<br>> +...<br>> +box.schema.user.grant('guest', 'execute', 'function', 'setuid')<br>> +---<br>> +...<br>> +box.schema.user.grant('guest', 'execute', 'function', 'escalation')<br>> +---<br>> +...<br>> +connection = net:connect(os.getenv("LISTEN"))<br>> +---<br>> +...<br>> +background = fiber.create(function() connection:call("setuid") end)<br>> +---<br>> +...<br>> +connection:call("escalation")<br>> +---<br>> +- error: Read access to space '_space' is denied for user 'guest'<br>> +...<br>> +channel:put(true)<br>> +---<br>> +- true<br>> +...<br>> +--<br>> +-- tear down the functions; the grants are dropped recursively<br>> +--<br>> +box.schema.func.drop('setuid')<br>> +---<br>> +...<br>> +box.schema.func.drop('escalation')<br>> +---<br>> +...<br>> +connection:close()<br>> +---<br>> +...<br>> diff --git a/test/box/access_escalation_gh-617.test.lua b/test/box/access_escalation_gh-617.test.lua<br>> new file mode 100644<br>> index 0000000..2c7b40f<br>> --- /dev/null<br>> +++ b/test/box/access_escalation_gh-617.test.lua<br>> @@ -0,0 +1,48 @@<br>> +fiber = require('fiber')<br>> +net = require('net.box')<br>> +os = require('os')<br>> +<br>> +-- gh-617: guest access denied because of setuid<br>> +-- function invocation.<br>> +<br>> +-- Test for privilege escalation<br>> +-- -----------------------------<br>> +-- * create a setuid function which changes effective id<br>> +-- to superuser<br>> +-- * invoke it via the binary protocol<br>> +-- * while the function is running, invoke a non-setuid function<br>> +-- which reads a system space.<br>> +--<br>> +-- The invoked function should get "Access denied" error,<br>> +-- there should be no privilege escalation.<br>> +<br>> +-- define functions<br>> +<br>> +channel = fiber.channel(1)<br>> +function setuid() channel:get() end<br>> +<br>> +function escalation() return box.space._space:get{box.schema.SPACE_ID} ~= nil end<br>> +<br>> +-- set up grants<br>> +<br>> +box.schema.func.create('setuid', {setuid=true})<br>> +box.schema.func.create('escalation')<br>> +<br>> +box.schema.user.grant('guest', 'execute', 'function', 'setuid')<br>> +box.schema.user.grant('guest', 'execute', 'function', 'escalation')<br>> +<br>> +<br>> +connection = net:connect(os.getenv("LISTEN"))<br>> +<br>> +background = fiber.create(function() connection:call("setuid") end)<br>> +connection:call("escalation")<br>> +channel:put(true)<br>> +<br>> +--<br>> +-- tear down the functions; the grants are dropped recursively<br>> +--<br>> +<br>> +box.schema.func.drop('setuid')<br>> +box.schema.func.drop('escalation')<br>> +<br>> +connection:close()<br>> --<br>> 1.8.3.1<br>></div><br>--<br>sergeyb@</div></div></div></div></blockquote> <div> </div><div data-signature-widget="container"><div data-signature-widget="content"><div>--<br>Alexander Tikhonov</div></div></div><div> </div></div></BODY></HTML>