From 4d2bc1f3cd36808120ffbee13af6e54c46071644 Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Tue, 7 Apr 2015 01:46:27 +0300
Subject: [PATCH] gh-508: suid functions fail

The bug was caused by incorrect check for universal access in SetuidGuard
and missing user id change thanks to it.

Fix a coding bug and add a test case.
Closes gh-508.
---
 src/box/lua/call.cc                   |  2 +-
 test/box/access_bin.result            | 44 +++++++++++++++++++++++++++
 test/box/access_bin.test.lua          | 18 +++++++++++
 test/replication/hot_standby.result   |  6 ++++
 test/replication/hot_standby.test.lua |  2 ++
 5 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc
index cc92cf7b75..c05f220068 100644
--- a/src/box/lua/call.cc
+++ b/src/box/lua/call.cc
@@ -478,7 +478,7 @@ SetuidGuard::SetuidGuard(const char *name, uint32_t name_len,
 	 * No special check for ADMIN user is necessary
 	 * since ADMIN has universal access.
 	 */
-	if (orig_credentials->universal_access & PRIV_ALL)
+	if ((orig_credentials->universal_access & PRIV_ALL) == PRIV_ALL)
 		return;
 	access &= ~orig_credentials->universal_access;
 	/*
diff --git a/test/box/access_bin.result b/test/box/access_bin.result
index 850c0c0c07..3dfc0a4172 100644
--- a/test/box/access_bin.result
+++ b/test/box/access_bin.result
@@ -285,3 +285,47 @@ box.schema.user.drop('test')
 test:drop()
 ---
 ...
+--
+-- gh-508 - wrong check for universal access of setuid functions
+--
+-- notice that guest can execute stuff, but can't read space _func
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
+function f1() return box.space._func:get(1)[4] end
+---
+...
+function f2() return box.space._func:get(2)[4] end
+---
+...
+box.schema.func.create('f1')
+---
+...
+box.schema.func.create('f2',{setuid=true})
+---
+...
+c = net.new(box.cfg.listen)
+---
+...
+-- should return access denied
+c:call('f1')
+---
+- error: Read access denied for user 'guest' to space '_func'
+...
+-- should work (used to return access denied, because was not setuid
+c:call('f2')
+---
+- - [0]
+...
+c:close()
+---
+...
+box.schema.user.revoke('guest', 'execute', 'universe')
+---
+...
+box.schema.func.drop('f1')
+---
+...
+box.schema.func.drop('f2')
+---
+...
diff --git a/test/box/access_bin.test.lua b/test/box/access_bin.test.lua
index be54595ba6..24019668e1 100644
--- a/test/box/access_bin.test.lua
+++ b/test/box/access_bin.test.lua
@@ -106,3 +106,21 @@ box.session.su('admin')
 c:close()
 box.schema.user.drop('test')
 test:drop()
+--
+-- gh-508 - wrong check for universal access of setuid functions
+--
+-- notice that guest can execute stuff, but can't read space _func
+box.schema.user.grant('guest', 'execute', 'universe')
+function f1() return box.space._func:get(1)[4] end
+function f2() return box.space._func:get(2)[4] end
+box.schema.func.create('f1')
+box.schema.func.create('f2',{setuid=true})
+c = net.new(box.cfg.listen)
+-- should return access denied
+c:call('f1')
+-- should work (used to return access denied, because was not setuid
+c:call('f2')
+c:close()
+box.schema.user.revoke('guest', 'execute', 'universe')
+box.schema.func.drop('f1')
+box.schema.func.drop('f2')
diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result
index 69ba5bc477..b6ccad365c 100644
--- a/test/replication/hot_standby.result
+++ b/test/replication/hot_standby.result
@@ -2,6 +2,12 @@
 box.schema.user.grant('guest', 'replication')
 ---
 ...
+box.schema.func.create('_set_pri_lsn')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', '_set_pri_lsn')
+---
+...
 --# create server hot_standby with script='replication/hot_standby.lua', rpl_master=default
 --# create server replica with rpl_master=default, script='replication/replica.lua'
 --# start server hot_standby
diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua
index e5865acc8e..68a5a6a432 100644
--- a/test/replication/hot_standby.test.lua
+++ b/test/replication/hot_standby.test.lua
@@ -1,5 +1,7 @@
 --# set connection default
 box.schema.user.grant('guest', 'replication')
+box.schema.func.create('_set_pri_lsn')
+box.schema.user.grant('guest', 'execute', 'function', '_set_pri_lsn')
 --# create server hot_standby with script='replication/hot_standby.lua', rpl_master=default
 --# create server replica with rpl_master=default, script='replication/replica.lua'
 --# start server hot_standby
-- 
GitLab