Skip to content

Commit f42dd80

Browse files
Merge pull request ClickHouse#87730 from ClickHouse/backport/25.8/87545
Backport ClickHouse#87545 to 25.8: Better access validation for `Buffer` engine.
2 parents 623aef2 + ebe26fb commit f42dd80

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

src/Storages/StorageBuffer.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <Storages/StorageBuffer.h>
22

3+
#include <Access/Common/AccessFlags.h>
34
#include <Analyzer/TableNode.h>
45
#include <Analyzer/Utils.h>
56
#include <Interpreters/Context.h>
@@ -290,6 +291,7 @@ void StorageBuffer::read(
290291

291292
if (auto destination = getDestinationTable())
292293
{
294+
local_context->checkAccess(AccessType::SELECT, destination->getStorageID(), column_names);
293295
auto destination_lock
294296
= destination->lockForShare(local_context->getCurrentQueryId(), local_context->getSettingsRef()[Setting::lock_acquire_timeout]);
295297

@@ -642,13 +644,14 @@ static void appendBlock(LoggerPtr log, const Block & from, Block & to)
642644
}
643645

644646

645-
class BufferSink : public SinkToStorage
647+
class BufferSink : public SinkToStorage, WithContext
646648
{
647649
public:
648650
explicit BufferSink(
649651
StorageBuffer & storage_,
650-
const StorageMetadataPtr & metadata_snapshot_)
651-
: SinkToStorage(std::make_shared<const Block>(metadata_snapshot_->getSampleBlock()))
652+
const StorageMetadataPtr & metadata_snapshot_,
653+
const ContextPtr & context_)
654+
: SinkToStorage(std::make_shared<const Block>(metadata_snapshot_->getSampleBlock())), WithContext(context_)
652655
, storage(storage_)
653656
, metadata_snapshot(metadata_snapshot_)
654657
{
@@ -669,6 +672,7 @@ class BufferSink : public SinkToStorage
669672
StoragePtr destination = storage.getDestinationTable();
670673
if (destination)
671674
{
675+
getContext()->checkAccess(AccessType::INSERT, destination->getStorageID());
672676
destination = DatabaseCatalog::instance().tryGetTable(storage.destination_id, storage.getContext());
673677
if (destination.get() == &storage)
674678
throw Exception(ErrorCodes::INFINITE_LOOP, "Destination table is myself. Write will cause infinite loop.");
@@ -766,9 +770,9 @@ class BufferSink : public SinkToStorage
766770
};
767771

768772

769-
SinkToStoragePtr StorageBuffer::write(const ASTPtr & /*query*/, const StorageMetadataPtr & metadata_snapshot, ContextPtr /*context*/, bool /*async_insert*/)
773+
SinkToStoragePtr StorageBuffer::write(const ASTPtr & /*query*/, const StorageMetadataPtr & metadata_snapshot, ContextPtr local_context, bool /*async_insert*/)
770774
{
771-
return std::make_shared<BufferSink>(*this, metadata_snapshot);
775+
return std::make_shared<BufferSink>(*this, metadata_snapshot, local_context);
772776
}
773777

774778

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
OK
2+
OK
3+
foo
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
# Tags: long, no-replicated-database, no-async-insert
3+
4+
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
5+
# shellcheck source=../shell_config.sh
6+
. "$CURDIR"/../shell_config.sh
7+
8+
9+
user="user03631_${CLICKHOUSE_DATABASE}_$RANDOM"
10+
db=${CLICKHOUSE_DATABASE}
11+
12+
${CLICKHOUSE_CLIENT} <<EOF
13+
CREATE TABLE $db.test_table (s String) ENGINE = MergeTree ORDER BY s;
14+
INSERT INTO $db.test_table VALUES ('foo');
15+
16+
DROP USER IF EXISTS $user;
17+
CREATE USER $user;
18+
GRANT SELECT, CREATE, INSERT ON $db.test_buffer TO $user;
19+
GRANT TABLE ENGINE ON Buffer TO $user;
20+
EOF
21+
22+
${CLICKHOUSE_CLIENT} --user $user --query "CREATE TABLE $db.test_buffer ENGINE = Buffer($db, test_table, 1, 10, 100, 10000, 1000000, 10000000, 100000000)"
23+
(( $(${CLICKHOUSE_CLIENT} --user $user --query "SELECT * FROM $db.test_buffer" 2>&1 | grep -c "Not enough privileges") >= 1 )) && echo "OK" || echo "UNEXPECTED"
24+
(( $(${CLICKHOUSE_CLIENT} --user $user --query "INSERT INTO $db.test_buffer VALUES ('bar')" 2>&1 | grep -c "Not enough privileges") >= 1 )) && echo "OK" || echo "UNEXPECTED"
25+
26+
${CLICKHOUSE_CLIENT} --query "GRANT SELECT ON $db.test_table TO $user"
27+
${CLICKHOUSE_CLIENT} --user $user --query "SELECT * FROM $db.test_buffer"
28+
29+
${CLICKHOUSE_CLIENT} --query "DROP USER IF EXISTS $user"

0 commit comments

Comments
 (0)