Skip to content

Commit

Permalink
Merge pull request #644 from arutk/list
Browse files Browse the repository at this point in the history
casadm robustness and security fixes
  • Loading branch information
Robert Baldyga authored Jan 21, 2021
2 parents 42ac206 + 2b739d1 commit be4920e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 27 deletions.
62 changes: 41 additions & 21 deletions casadm/cas_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,24 @@ cas_printf_t cas_printf = std_printf;
int validate_dev(const char *dev_path)
{
struct fstab *fstab_entry;
struct stat status;

fstab_entry = getfsspec(dev_path);
if (fstab_entry != NULL) {
printf("Device entry present in fstab, please remove it.\n");
return FAILURE;
}

if (stat(dev_path, &status) == -1) {
printf("Failed to query device status.\n");
return FAILURE;
}

if (!S_ISBLK(status.st_mode)) {
printf("Path does not describe a block device\n");
return FAILURE;
}

return SUCCESS;
}

Expand Down Expand Up @@ -540,11 +554,9 @@ const char *get_core_state_name(int core_state)
/* check if device is atomic and print information about potential slow start */
void print_slow_atomic_cache_start_info(const char *device_path)
{
char buff[MAX_STR_LEN];
struct kcas_cache_check_device cmd_info;
int ret;

get_dev_path(device_path, buff, sizeof(buff));
ret = _check_cache_device(device_path, &cmd_info);

if (!ret && cmd_info.format_atomic) {
Expand Down Expand Up @@ -632,6 +644,7 @@ static bool is_dev_link_whitelisted(const char* path)
return false;
}

/* Call this only AFTER normalizing path */
static int _is_by_id_path(const char* dev_path)
{
static const char dev_by_id_dir[] = "/dev/disk/by-id";
Expand All @@ -653,8 +666,7 @@ int set_device_path(char *dest_path, size_t dest_len, const char *src_path, size

/* check if given dev_path is whitelisted and then pass it as path or not */
if (is_dev_link_whitelisted(abs_dev_path)){
result = strncpy_s(dest_path, dest_len, abs_dev_path,
strnlen_s(abs_dev_path, sizeof(abs_dev_path)));
result = strncpy_s(dest_path, dest_len, abs_dev_path, sizeof(abs_dev_path));
return result ?: SUCCESS;
}

Expand Down Expand Up @@ -820,11 +832,14 @@ struct cache_device *get_cache_device(const struct kcas_cache_info *info, bool b
cache->expected_core_count = info->info.core_count;
cache->id = cache_id;
cache->state = info->info.state;
if (set_device_path(cache->device, sizeof(cache->device), info->cache_path_name,
sizeof(info->cache_path_name)) != SUCCESS) {

if (strncpy_s(cache->device, sizeof(cache->device),
info->cache_path_name,
sizeof(info->cache_path_name))) {
free(cache);
return NULL;
}

cache->mode = info->info.cache_mode;
cache->dirty = info->info.dirty;
cache->flushed = info->info.flushed;
Expand Down Expand Up @@ -2753,8 +2768,11 @@ int list_caches(unsigned int list_format, bool by_id_path)
float core_flush_prog;

if (!by_id_path) {
get_dev_path(curr_cache->device, curr_cache->device,
sizeof(curr_cache->device));
if (get_dev_path(curr_cache->device, curr_cache->device,
sizeof(curr_cache->device))) {
cas_printf(LOG_WARNING, "WARNING: Cannot resolve path "
"to cache. By-id path will be shown for that cache.\n");
}
}

cache_flush_prog = calculate_flush_progress(curr_cache->dirty, curr_cache->flushed);
Expand Down Expand Up @@ -2831,6 +2849,11 @@ int _check_cache_device(const char *device_path,
{
int result, fd;

if (strncpy_s(cmd_info->path_name, sizeof(cmd_info->path_name),
device_path, MAX_STR_LEN)) {
return FAILURE;
}

fd = open_ctrl_device();
if (fd == -1)
return FAILURE;
Expand All @@ -2839,7 +2862,7 @@ int _check_cache_device(const char *device_path,

close(fd);

return result;
return result ? FAILURE : SUCCESS;
}

int check_cache_device(const char *device_path)
Expand Down Expand Up @@ -2892,21 +2915,16 @@ int zero_md(const char *cache_device){
int fd = 0;
int result;

/* check if given cache device exists */
fd = open(cache_device, O_RDONLY);
/* check if device is available */
fd = open(cache_device, O_WRONLY | O_SYNC | O_EXCL);
if (fd < 0) {
cas_printf(LOG_ERR, "Device '%s' not found.\n", cache_device);
cas_printf(LOG_ERR, "Error while opening '%s'exclusively. This can be due to\n"
"cache instance running on this device. In such case please "
"stop the cache and try again.\n", cache_device);
return FAILURE;
}
close(fd);

/* don't delete metadata if cache is in use */
if (check_cache_already_added(cache_device) == FAILURE) {
cas_printf(LOG_ERR, "Cache device '%s' is already used as cache. "
"Please stop cache to clear metadata.\n", cache_device);
return FAILURE;
}

result = _check_cache_device(cache_device, &cmd_info);
if (result == FAILURE) {
cas_printf(LOG_ERR, "Failed to retrieve device's information.\n");
Expand All @@ -2919,9 +2937,11 @@ int zero_md(const char *cache_device){
return FAILURE;
}

fd = open(cache_device, O_WRONLY | O_SYNC);
fd = open(cache_device, O_WRONLY | O_SYNC | O_EXCL);
if (fd < 0) {
cas_printf(LOG_ERR, "Error while opening '%s' to purge metadata.\n", cache_device);
cas_printf(LOG_ERR, "Error while opening '%s'exclusively. This can be due to\n"
"cache instance running on this device. In such case please\n"
"stop the cache and try again.\n", cache_device);
return FAILURE;
}

Expand Down
9 changes: 3 additions & 6 deletions casadm/cas_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,13 @@ static struct command_args command_args_values = {
};

int validate_device_name(const char *dev_name) {
if (validate_dev(dev_name)) {
cas_printf(LOG_ERR, "Cache creation aborted, %s entry exists in /etc/fstab. Please remove it!\n",
dev_name);
if (strnlen(dev_name, MAX_STR_LEN) >= MAX_STR_LEN) {
cas_printf(LOG_ERR, "Illegal device name\n");
return FAILURE;
}

if (strnlen(dev_name, MAX_STR_LEN) >= MAX_STR_LEN) {
cas_printf(LOG_ERR, "Illegal device %s\n", dev_name);
if (validate_dev(dev_name))
return FAILURE;
}

return SUCCESS;
}
Expand Down

0 comments on commit be4920e

Please sign in to comment.