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