From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 66D302C3EB for ; Thu, 11 Oct 2018 04:53:20 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Vz-Goq0Ry50y for ; Thu, 11 Oct 2018 04:53:20 -0400 (EDT) Received: from smtp39.i.mail.ru (smtp39.i.mail.ru [94.100.177.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id B72262C41F for ; Thu, 11 Oct 2018 04:53:19 -0400 (EDT) From: Kirill Yukhin Subject: [tarantool-patches] [PATCH] sql: check read access while executing SQL query Date: Thu, 11 Oct 2018 11:53:11 +0300 Message-Id: <6dc6ee8b0356676cf6176dd6310109a09ce7b23d.1539247804.git.kyukhin@tarantool.org> Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: korablev@tarantool.org Cc: tarantool-patches@freelists.org, Kirill Yukhin Since SQL front-end is not using box API, no checkes for read access are performed by VDBE engine. Fix this by introducing dedicated opcode which is executed to perform read access check. Note, that there's is no need to perform DML/DDL checkes as they're performed by Tarantool's core. Closes #2362 --- https://github.com/tarantool/tarantool/commits/kyukhin/gh-2362-sql-read-access-check https://github.com/tarantool/tarantool/issues/2362 src/box/sql/vdbe.c | 6 ++ test/sql/gh-2362-select-access-rights.result | 113 +++++++++++++++++++++++++ test/sql/gh-2362-select-access-rights.test.lua | 44 ++++++++++ 3 files changed, 163 insertions(+) create mode 100644 test/sql/gh-2362-select-access-rights.result create mode 100644 test/sql/gh-2362-select-access-rights.test.lua diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 7c1015c..b4e2269 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -3099,8 +3099,14 @@ case OP_IteratorOpen: else space = aMem[pOp->p3].u.p; assert(space != NULL); + if (access_check_space(space, PRIV_R) != 0) { + rc = SQL_TARANTOOL_ERROR; + goto abort_due_to_error; + } + struct index *index = space_index(space, pOp->p2); assert(index != NULL); + assert(pOp->p1 >= 0); cur = allocateCursor(p, pOp->p1, space->def->exact_field_count == 0 ? diff --git a/test/sql/gh-2362-select-access-rights.result b/test/sql/gh-2362-select-access-rights.result new file mode 100644 index 0000000..1f0ca94 --- /dev/null +++ b/test/sql/gh-2362-select-access-rights.result @@ -0,0 +1,113 @@ +test_run = require('test_run').new() +--- +... +engine = test_run:get_cfg('engine') +--- +... +nb = require('net.box') +--- +... +box.sql.execute("PRAGMA sql_default_engine='"..engine.."'") +--- +... +box.sql.execute("CREATE TABLE t1 (s1 INT PRIMARY KEY, s2 INT UNIQUE);") +--- +... +box.sql.execute("CREATE TABLE t2 (s1 INT PRIMARY KEY);") +--- +... +box.sql.execute("INSERT INTO t1 VALUES (1, 1);") +--- +... +box.sql.execute("INSERT INTO t2 VALUES (1);") +--- +... +box.schema.user.grant('guest','read', 'space', '_space') +--- +... +box.schema.user.grant('guest','read', 'space', 'T1') +--- +... +c = nb.connect(box.cfg.listen) +--- +... +c:execute("SELECT * FROM t1;") +--- +- metadata: + - name: S1 + - name: S2 + rows: + - [1, 1] +... +box.schema.user.revoke('guest','read', 'space', 'T1') +--- +... +c = nb.connect(box.cfg.listen) +--- +... +c:execute("SELECT * FROM t1;") +--- +- error: 'Failed to execute SQL statement: Read access to space ''T1'' is denied for + user ''guest''' +... +box.schema.user.grant('guest','read', 'space', 'T2') +--- +... +c = nb.connect(box.cfg.listen) +--- +... +c:execute('SELECT * FROM t1, t2 WHERE t1.s1 = t2.s1') +--- +- error: 'Failed to execute SQL statement: Read access to space ''T1'' is denied for + user ''guest''' +... +box.sql.execute("CREATE VIEW v AS SELECT * FROM t1") +--- +... +box.schema.user.grant('guest','read', 'space', 'V') +--- +... +v = nb.connect(box.cfg.listen) +--- +... +c:execute('SELECT * FROM v') +--- +- error: 'Failed to execute SQL statement: Read access to space ''T1'' is denied for + user ''guest''' +... +box.sql.execute('CREATE TABLE t3 (s1 INT PRIMARY KEY, fk INT, FOREIGN KEY (fk) REFERENCES t1(s2))') +--- +... +box.schema.user.grant('guest','read','space', 'T3') +--- +... +v = nb.connect(box.cfg.listen) +--- +... +c:execute('INSERT INTO t3 VALUES (1, 1)') +--- +- error: 'Failed to execute SQL statement: Read access to space ''T1'' is denied for + user ''guest''' +... +-- Cleanup +box.schema.user.revoke('guest','read','space', 'V') +--- +... +box.schema.user.revoke('guest','read','space', 'T2') +--- +... +box.schema.user.revoke('guest','read','space', 'T3') +--- +... +box.sql.execute('DROP VIEW v') +--- +... +box.sql.execute('DROP TABLE t3') +--- +... +box.sql.execute('DROP TABLE t2') +--- +... +box.sql.execute("DROP TABLE t1") +--- +... diff --git a/test/sql/gh-2362-select-access-rights.test.lua b/test/sql/gh-2362-select-access-rights.test.lua new file mode 100644 index 0000000..159373c --- /dev/null +++ b/test/sql/gh-2362-select-access-rights.test.lua @@ -0,0 +1,44 @@ +test_run = require('test_run').new() +engine = test_run:get_cfg('engine') +nb = require('net.box') + +box.sql.execute("PRAGMA sql_default_engine='"..engine.."'") +box.sql.execute("CREATE TABLE t1 (s1 INT PRIMARY KEY, s2 INT UNIQUE);") +box.sql.execute("CREATE TABLE t2 (s1 INT PRIMARY KEY);") +box.sql.execute("INSERT INTO t1 VALUES (1, 1);") +box.sql.execute("INSERT INTO t2 VALUES (1);") + +box.schema.user.grant('guest','read', 'space', '_space') + +box.schema.user.grant('guest','read', 'space', 'T1') +c = nb.connect(box.cfg.listen) +c:execute("SELECT * FROM t1;") + +box.schema.user.revoke('guest','read', 'space', 'T1') +c = nb.connect(box.cfg.listen) +c:execute("SELECT * FROM t1;") + +box.schema.user.grant('guest','read', 'space', 'T2') +c = nb.connect(box.cfg.listen) +c:execute('SELECT * FROM t1, t2 WHERE t1.s1 = t2.s1') + +box.sql.execute("CREATE VIEW v AS SELECT * FROM t1") + +box.schema.user.grant('guest','read', 'space', 'V') +v = nb.connect(box.cfg.listen) +c:execute('SELECT * FROM v') + +box.sql.execute('CREATE TABLE t3 (s1 INT PRIMARY KEY, fk INT, FOREIGN KEY (fk) REFERENCES t1(s2))') +box.schema.user.grant('guest','read','space', 'T3') +v = nb.connect(box.cfg.listen) +c:execute('INSERT INTO t3 VALUES (1, 1)') + +-- Cleanup +box.schema.user.revoke('guest','read','space', 'V') +box.schema.user.revoke('guest','read','space', 'T2') +box.schema.user.revoke('guest','read','space', 'T3') + +box.sql.execute('DROP VIEW v') +box.sql.execute('DROP TABLE t3') +box.sql.execute('DROP TABLE t2') +box.sql.execute("DROP TABLE t1") -- 2.11.0