mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Fix TOCTOU while checking for container existence in azure_blob_storage
This is a simple time-of-check vs time-of-use, since between checking does such container exist and creating one, there is a time window. Signed-off-by: Azat Khuzhin <a.khuzhin@semrush.com>
This commit is contained in:
parent
38c001ca42
commit
fe832c4418
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#if USE_AZURE_BLOB_STORAGE
|
#if USE_AZURE_BLOB_STORAGE
|
||||||
|
|
||||||
|
#include <Common/Exception.h>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <re2/re2.h>
|
#include <re2/re2.h>
|
||||||
#include <azure/identity/managed_identity_credential.hpp>
|
#include <azure/identity/managed_identity_credential.hpp>
|
||||||
@ -125,21 +126,22 @@ std::unique_ptr<BlobContainerClient> getAzureBlobContainerClient(
|
|||||||
|
|
||||||
auto blob_service_client = getAzureBlobStorageClientWithAuth<BlobServiceClient>(endpoint.storage_account_url, container_name, config, config_prefix);
|
auto blob_service_client = getAzureBlobStorageClientWithAuth<BlobServiceClient>(endpoint.storage_account_url, container_name, config, config_prefix);
|
||||||
|
|
||||||
if (!endpoint.container_already_exists.has_value())
|
try
|
||||||
{
|
{
|
||||||
ListBlobContainersOptions blob_containers_list_options;
|
return std::make_unique<BlobContainerClient>(
|
||||||
blob_containers_list_options.Prefix = container_name;
|
blob_service_client->CreateBlobContainer(container_name).Value);
|
||||||
blob_containers_list_options.PageSizeHint = 1;
|
}
|
||||||
auto blob_containers = blob_service_client->ListBlobContainers().BlobContainers;
|
catch (const Azure::Storage::StorageException & e)
|
||||||
for (const auto & blob_container : blob_containers)
|
{
|
||||||
{
|
/// If container_already_exists is not set (in config), ignore already exists error.
|
||||||
if (blob_container.Name == endpoint.container_name)
|
/// (Conflict - The specified container already exists)
|
||||||
return getAzureBlobStorageClientWithAuth<BlobContainerClient>(final_url, container_name, config, config_prefix);
|
if (!endpoint.container_already_exists.has_value() && e.StatusCode == Azure::Core::Http::HttpStatusCode::Conflict)
|
||||||
}
|
{
|
||||||
|
tryLogCurrentException("Container already exist, return existing container");
|
||||||
|
return getAzureBlobStorageClientWithAuth<BlobContainerClient>(final_url, container_name, config, config_prefix);
|
||||||
|
}
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_unique<BlobContainerClient>(
|
|
||||||
blob_service_client->CreateBlobContainer(container_name).Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AzureObjectStorageSettings> getAzureBlobStorageSettings(const Poco::Util::AbstractConfiguration & config, const String & config_prefix, ContextPtr /*context*/)
|
std::unique_ptr<AzureObjectStorageSettings> getAzureBlobStorageSettings(const Poco::Util::AbstractConfiguration & config, const String & config_prefix, ContextPtr /*context*/)
|
||||||
|
Loading…
Reference in New Issue
Block a user