Hi Oleg, LGTM, please proceed to Kirill to push.

 
Вторник, 24 марта 2020, 11:12 +03:00 от Sergey Bronnikov <sergeyb@tarantool.org>:
 
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