1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
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()
---
...
|