From 975ec6f32a3173b0171178e62f1964d1907b49ee Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Mon, 15 Jun 2020 10:26:26 -0400 Subject: [PATCH 1/2] Keep pointer to rollback thread in start_finalize If cache is initialized successfully, `struct _cache_mngt_attach_context` might be freed in `cache_mngt_init_instance()`. In such case pointer to rollback thread can't be accessed and thread can't be stopped. To prevent such scenario pointer should be kept in separate variable. Signed-off-by: Michal Mielewczyk --- modules/cas_cache/layer_cache_management.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index 84d01b5..e3d31fc 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -1848,6 +1848,7 @@ static void cache_start_finalize(struct work_struct *work) { struct cache_priv *cache_priv = container_of(work, struct cache_priv, start_worker); + struct task_struct *rollback_thread; struct _cache_mngt_attach_context *ctx = cache_priv->attach_context; int result; ocf_cache_t cache = ctx->cache; @@ -1870,6 +1871,8 @@ static void cache_start_finalize(struct work_struct *work) init_instance_complete(ctx, cache); + rollback_thread = ctx->rollback_thread; + if (_cache_mngt_async_callee_set_result(&ctx->async, 0)) { /* caller interrupted */ ctx->ocf_start_error = 0; @@ -1878,7 +1881,7 @@ static void cache_start_finalize(struct work_struct *work) return; } - kthread_stop(ctx->rollback_thread); + kthread_stop(rollback_thread); ocf_mngt_cache_unlock(cache); } From c71b5fcbd3ab1476a40e28a3db68dc28d3be512e Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 16 Jun 2020 04:01:54 -0400 Subject: [PATCH 2/2] Access attach command conditionaly If cache is restored after upgrade, NULL is passed instead of `struct kcas_start_cache`. This leads to null pointer dereference. To prevent null pointer dereference, `struct kcas_start_cache` is tested before each use Signed-off-by: Michal Mielewczyk --- modules/cas_cache/layer_cache_management.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index e3d31fc..7ee0bd4 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -1836,7 +1836,7 @@ static void init_instance_complete(struct _cache_mngt_attach_context *ctx, /* Set other back information */ name = block_dev_get_elevator_name( casdsk_disk_get_queue(bd_cache_obj->dsk)); - if (name) + if (name && ctx->cmd) strlcpy(ctx->cmd->cache_elevator, name, MAX_ELEVATOR_NAME); } @@ -1893,7 +1893,7 @@ static void _cache_mngt_start_complete(ocf_cache_t cache, void *priv, int error) int caller_status = _cache_mngt_async_callee_peek_result(&ctx->async); if (caller_status || error) { - if (error == -OCF_ERR_NO_FREE_RAM) { + if (error == -OCF_ERR_NO_FREE_RAM && ctx->cmd) { ocf_mngt_get_ram_needed(cache, ctx->device_cfg, &ctx->cmd->min_free_ram); } else if (caller_status == -KCAS_ERR_WAITING_INTERRUPTED) {