From patchwork Tue Oct 22 07:12:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming-Hung Tsai X-Patchwork-Id: 13845226 X-Patchwork-Delegate: mpatocka@redhat.com Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 143DA13AD0 for ; Tue, 22 Oct 2024 07:12:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581180; cv=none; b=mCRtnG8wwIFuUAWA9ZwByhfZhLNDY4HC7aO/mcKX+64Lr6BtSaNqaWg59sCgP8dEvs+IuXn+2ybOB2+yDs7O1wsuZAvuMiZNjG0nbt3zOtw0T6DGnFcKwLUsAKuJTxRVYWMmr2yEKsF2S/pyv6twrIHN6IKJr/hF1BxVVaQ5tjs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581180; c=relaxed/simple; bh=/CiqqNEJ10PN1QWvkqC8BJSrhjzsHEuV9cVXQY+Xujo=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=HlSOowbW8GhDkvhxQhDqq5Va3UeT4xrVZUc2REatAkuCao3AxkbpeAWn+oJEvtlRtLlwtfOVSMYJuOYlsioDeiZPxSJD687p4B5Mmuf/4AJdbP+A4Ei8zXHIEfCIP7grpeZ11X9XTAoEp2C+L8ApaNk80a0Cy7f9mdKYpfR1ARg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=e321+mg+; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="e321+mg+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1729581178; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=AGi2mNoYkyktpfBeiA2epz+j1luH8CIv62zEtu27bBg=; b=e321+mg+03w1V6dGvEBUD75Xtgrm7NxRWkZkZ73/zsIhSnEufHVrKM/QmXmSTm6f7e8FLV UQsBOA1kN0UcVJ9bxI7JdPTxSkz9uU9ol9mTrwnp30+H1EfQLQzKI8NroOfwat239c4K90 31gmk7mzOZQYp4e5Gv4z51CwqnlBOOg= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-53-fcXokd_FPS2KzMfqi2I_TA-1; Tue, 22 Oct 2024 03:12:54 -0400 X-MC-Unique: fcXokd_FPS2KzMfqi2I_TA-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D125B1955D71; Tue, 22 Oct 2024 07:12:53 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.67.24.92]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0363319560A2; Tue, 22 Oct 2024 07:12:44 +0000 (UTC) From: Ming-Hung Tsai To: dm-devel@lists.linux.dev Cc: mpatocka@redhat.com, thornber@redhat.com, heinzm@redhat.com, snitzer@kernel.org, Ming-Hung Tsai Subject: [PATCH 1/5] dm cache: correct the number of origin blocks to match the target length Date: Tue, 22 Oct 2024 15:12:22 +0800 Message-ID: <20241022071222.778553-1-mtsai@redhat.com> Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com When creating a cache device, the actual size of the cache origin might be greater than the specified cache target length. In such case, the number of origin blocks should match the cache target length, not the full size of the origin device, since access beyond the cache target is not possible. This issue occurs when reducing the origin device size using lvm, as lvreduce preloads the new cache table before resuming the cache origin, which can result in incorrect sizes for the discard bitset and smq hotspot blocks. Reproduce steps: 1. create a cache device consists of 4096 origin blocks dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" dmsetup create corig --table "0 524288 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" 2. reduce the cache origin to 2048 oblocks, in lvreduce's approach dmsetup reload corig --table "0 262144 linear /dev/sdc 262144" dmsetup reload cache --table "0 262144 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" dmsetup suspend cache dmsetup suspend corig dmsetup suspend cdata dmsetup suspend cmeta dmsetup resume corig dmsetup resume cdata dmsetup resume cmeta dmsetup resume cache 3. shutdown the cache, and check the number of discard blocks in superblock. The value is expected to be 2048, but actually is 4096. dmsetup remove cache corig cdata cmeta dd if=/dev/sdc bs=1c count=8 skip=224 2>/dev/null | hexdump -e '1/8 "%u\n"' Fix by correcting the origin_blocks initialization in cache_create and removing the unused origin_sectors from struct cache_args accordingly. Signed-off-by: Ming-Hung Tsai Fixes: c6b4fcbad044 ("dm: add cache target") --- drivers/md/dm-cache-target.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index aaeeabfab09b..90772b42c234 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2003,7 +2003,6 @@ struct cache_args { sector_t cache_sectors; struct dm_dev *origin_dev; - sector_t origin_sectors; uint32_t block_size; @@ -2084,6 +2083,7 @@ static int parse_cache_dev(struct cache_args *ca, struct dm_arg_set *as, static int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as, char **error) { + sector_t origin_sectors; int r; if (!at_least_one_arg(as, error)) @@ -2096,8 +2096,8 @@ static int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as, return r; } - ca->origin_sectors = get_dev_size(ca->origin_dev); - if (ca->ti->len > ca->origin_sectors) { + origin_sectors = get_dev_size(ca->origin_dev); + if (ca->ti->len > origin_sectors) { *error = "Device size larger than cached device"; return -EINVAL; } @@ -2407,7 +2407,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) ca->metadata_dev = ca->origin_dev = ca->cache_dev = NULL; - origin_blocks = cache->origin_sectors = ca->origin_sectors; + origin_blocks = cache->origin_sectors = ti->len; origin_blocks = block_div(origin_blocks, ca->block_size); cache->origin_blocks = to_oblock(origin_blocks); From patchwork Tue Oct 22 07:12:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming-Hung Tsai X-Patchwork-Id: 13845227 X-Patchwork-Delegate: mpatocka@redhat.com Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79504811EB for ; Tue, 22 Oct 2024 07:13:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581203; cv=none; b=eERh+XSUWMChb9t8T1q23bF6NylaZSLLvQon5F5CZwtHEIH4ElhDcy14E0UEJFBX8FAb5bJCbr73CYfulFIsleOag1VZJsWEkAvDkw9+8EoYZh3BeKMxziSBFgTJGYeW/amXnLKWfQq9km30wx8uTJFb+8cSg5F9i9B/M2rE1wU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581203; c=relaxed/simple; bh=unU4UT6uHhuCMbnR3FDf75CJxVt9vCvUoOXnUuj6lYs=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=pCYCOKRuzUXv4IDGonnihpbb6Xy1SrCaGKzP3O+Z1B9RbVUg9ZLJvxk0CuNAFiM9cPJDvLCPalMtVoLo85S7dF5hzRNQ2IfRJcJSFJ42C12ESVEkMLBzPXhhdBgzKEtwnbyUFp0dLBTilcj7SV9malyhBKh6eexIWIjQxdE6Zi0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=NtPCR6Lf; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="NtPCR6Lf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1729581200; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=IVpuDtQU3pAVsys2rDmJn13j/4rUMXRgZrmwgtPiep8=; b=NtPCR6LfWOYy7POA5UOUo/Wwrsl4wl+JB0Tki4swP8R4fe2rBZp2nbzgArLpQqCEjLH0w5 cKl1li5VfgVWcMtroJrJP6tpZB4MDbx5uyDq8IkmI1sibYgLRmLgOFIS9y/4H7Nzl+Sdri nhz1AYridmqEGsuOpnpXPAcJ1Uzjsng= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-288-ZIiRLEW3Oo6I02T16cFZ9g-1; Tue, 22 Oct 2024 03:13:17 -0400 X-MC-Unique: ZIiRLEW3Oo6I02T16cFZ9g-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2FE331956089; Tue, 22 Oct 2024 07:13:16 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.67.24.92]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 29C4319560B2; Tue, 22 Oct 2024 07:13:11 +0000 (UTC) From: Ming-Hung Tsai To: dm-devel@lists.linux.dev Cc: mpatocka@redhat.com, thornber@redhat.com, heinzm@redhat.com, snitzer@kernel.org, luomeng12@huawei.com, Ming-Hung Tsai Subject: [PATCH 2/5] dm cache: fix flushing uninitialized delayed_work on cache_ctr error Date: Tue, 22 Oct 2024 15:12:49 +0800 Message-ID: <20241022071249.778584-1-mtsai@redhat.com> Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com An unexpected WARN_ON from flush_work() may occur when cache creation fails, caused by destroying the uninitialized delayed_work waker in the error path of cache_create(). For example, the warning appears on the superblock checksum error. Reproduce steps: dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" dmsetup create corig --table "0 524288 linear /dev/sdc 262144" dd if=/dev/urandom of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" Kernel logs: (snip) WARNING: CPU: 0 PID: 84 at kernel/workqueue.c:4178 __flush_work+0x5d4/0x890 Fix by pulling out the cancel_delayed_work_sync() from the constructor's error path. This patch doesn't affect the use-after-free fix for concurrent dm_resume and dm_destroy (commit 6a459d8edbdb ("dm cache: Fix UAF in destroy()")) as cache_dtr is not changed. Signed-off-by: Ming-Hung Tsai Fixes: 6a459d8edbdb ("dm cache: Fix UAF in destroy()") --- drivers/md/dm-cache-target.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 90772b42c234..68e9a1abd303 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -1905,16 +1905,13 @@ static void check_migrations(struct work_struct *ws) * This function gets called on the error paths of the constructor, so we * have to cope with a partially initialised struct. */ -static void destroy(struct cache *cache) +static void __destroy(struct cache *cache) { - unsigned int i; - mempool_exit(&cache->migration_pool); if (cache->prison) dm_bio_prison_destroy_v2(cache->prison); - cancel_delayed_work_sync(&cache->waker); if (cache->wq) destroy_workqueue(cache->wq); @@ -1942,13 +1939,22 @@ static void destroy(struct cache *cache) if (cache->policy) dm_cache_policy_destroy(cache->policy); + bioset_exit(&cache->bs); + + kfree(cache); +} + +static void destroy(struct cache *cache) +{ + unsigned int i; + + cancel_delayed_work_sync(&cache->waker); + for (i = 0; i < cache->nr_ctr_args ; i++) kfree(cache->ctr_args[i]); kfree(cache->ctr_args); - bioset_exit(&cache->bs); - - kfree(cache); + __destroy(cache); } static void cache_dtr(struct dm_target *ti) @@ -2561,7 +2567,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) *result = cache; return 0; bad: - destroy(cache); + __destroy(cache); return r; } @@ -2612,7 +2618,7 @@ static int cache_ctr(struct dm_target *ti, unsigned int argc, char **argv) r = copy_ctr_args(cache, argc - 3, (const char **)argv + 3); if (r) { - destroy(cache); + __destroy(cache); goto out; } From patchwork Tue Oct 22 07:13:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming-Hung Tsai X-Patchwork-Id: 13845228 X-Patchwork-Delegate: mpatocka@redhat.com Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 409BD148FE6 for ; Tue, 22 Oct 2024 07:13:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581223; cv=none; b=owzCd7y4wbIErHWL3PXbjYlzZyY9hFvLm1uAjavDBC9Zx0b68ITj8EvMHsW3DAt9yZ38c44t5DnTkR2MF3cf8lfUK04H9F3/fGpwJMnb1GdSZIBQmXZg+8eq4AolYPz5KGaRjhiDnkFto0fYzwbx6UeZCnftIz56P1KeoGwbsXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581223; c=relaxed/simple; bh=HziE+9R9hbAULDhZfQfMVIYcLf8bwHGg5b/8sQ/CIsU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=A+XHN7HWkhg2Daqek5y8IGZMerZfpXr1jluTucnytyhjHN/lQFZKYdJ1B6eRFXmCc3KTjlYr6zSFfdYaviGJBGX/UGZNwpc2aYIzA5NnHIl3f4bM5UgQGuKZT8Ht9RIYDdao62fL5N3p9DYnPYPBZNNuy8OLf2OcPdrg/wAhURY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=E2tLMpSm; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="E2tLMpSm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1729581221; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Cg8EzfYlEr6Qde/+EDpQcl/0vJfF0E9uTITWkJfKrUY=; b=E2tLMpSmgG0LbHvnOOlcxiy6SbxjP3WnzfVU/l+95llmFdG2MZ7Aoo9060KC/pschF+za3 oF+LV5lcS4xLPYcM9u4aS11BhaxCpA5nn5kSHn8qhcDUVHuo1FLYfPdK5hz4iKdGUCyBR0 7jTTRgyIMW/xke3sa2SmqN0h3WKlYiE= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-220-lk8F_xQCOFKVmn16bTxPLw-1; Tue, 22 Oct 2024 03:13:40 -0400 X-MC-Unique: lk8F_xQCOFKVmn16bTxPLw-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1ECB51956096; Tue, 22 Oct 2024 07:13:39 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.67.24.92]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9E2801955F43; Tue, 22 Oct 2024 07:13:35 +0000 (UTC) From: Ming-Hung Tsai To: dm-devel@lists.linux.dev Cc: mpatocka@redhat.com, thornber@redhat.com, heinzm@redhat.com, snitzer@kernel.org, Ming-Hung Tsai Subject: [PATCH 3/5] dm cache: fix out-of-bounds access to the dirty bitset when resizing Date: Tue, 22 Oct 2024 15:13:16 +0800 Message-ID: <20241022071316.778660-1-mtsai@redhat.com> Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com dm-cache checks the dirty bits of the cache blocks to be dropped when shrinking the fast device, but an index bug in bitset iteration causes out-of-bounds access. Reproduce steps: 1. create a cache device of 1024 cache blocks (128 bytes dirty bitset) dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" dmsetup create corig --table "0 524288 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" 2. shrink the fast device to 512 cache blocks, triggering out-of-bounds access to the dirty bitset (offset 0x80) dmsetup suspend cache dmsetup reload cdata --table "0 65536 linear /dev/sdc 8192" dmsetup resume cdata dmsetup resume cache KASAN reports: BUG: KASAN: vmalloc-out-of-bounds in cache_preresume+0x269/0x7b0 Read of size 8 at addr ffffc900000f3080 by task dmsetup/131 (...snip...) The buggy address belongs to the virtual mapping at [ffffc900000f3000, ffffc900000f5000) created by: cache_ctr+0x176a/0x35f0 (...snip...) Memory state around the buggy address: ffffc900000f2f80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ffffc900000f3000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffffc900000f3080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ^ ffffc900000f3100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ffffc900000f3180: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 Fix by making the index post-incremented. Signed-off-by: Ming-Hung Tsai Fixes: f494a9c6b1b6 ("dm cache: cache shrinking support") --- drivers/md/dm-cache-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 68e9a1abd303..1fcd8c5c220e 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2912,13 +2912,13 @@ static bool can_resize(struct cache *cache, dm_cblock_t new_size) * We can't drop a dirty block when shrinking the cache. */ while (from_cblock(new_size) < from_cblock(cache->cache_size)) { - new_size = to_cblock(from_cblock(new_size) + 1); if (is_dirty(cache, new_size)) { DMERR("%s: unable to shrink cache; cache block %llu is dirty", cache_device_name(cache), (unsigned long long) from_cblock(new_size)); return false; } + new_size = to_cblock(from_cblock(new_size) + 1); } return true; From patchwork Tue Oct 22 07:13:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming-Hung Tsai X-Patchwork-Id: 13845229 X-Patchwork-Delegate: mpatocka@redhat.com Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8DE313BC12 for ; Tue, 22 Oct 2024 07:13:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581238; cv=none; b=MWBEpDPCL3eXgTTFpDw0J2Iqk00zMUefToBwjRRLj+mf9BU+ISXWHcZ31G4Zu4kUq54pAYwyKWcpKlegWN1ohyKNQN0KdyIL7udTnWIhw4oibk7tCGY05M0MAIbeCkW8Q0Po8gz+H1iVSByJ0iogOPfV07/FPHYw2cTUReohONQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581238; c=relaxed/simple; bh=gwK4nLcEWbOb6Qnn4KUs5J7cY0+KlvIaOWXxcpUib6Y=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=GMn/pKT5U22EJVV2lxd/HJrKfDb8CYwQqwY4O990uL5rysFanYOwkXv8glK29z0gzoUQIlxUpt6UsrM7oS+oQLAqCDQW5EZTU6x5AAHNRi2MLydRTawSCG6KoxuZFQZ2Gu1H8m9RxnAwJJYbOpFt/zkFRdPyqskL36ju5NXXu34= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=I1ClTMvI; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="I1ClTMvI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1729581235; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=45S4woCfEzn6e5MeMHLnioE0CFco3SKDnBWQLtC3JXE=; b=I1ClTMvImjBEwrySBjNaiCc2yo/3+u8F5QWl3EEnxdGC7fIncIsZh+WaKdljQzdEhviqnV F8Z2dY0nA5KHJsblbwdd5bDtbbwxQKkQipPEJAoQC3FQvF6r4ivZCYxqzqyLmtxI7osXIr i6RGgbl3E0nsr1AFeOK31R/n2ElD9js= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-601-QrPuuSaKP4CQ5bg5jWaX0w-1; Tue, 22 Oct 2024 03:13:54 -0400 X-MC-Unique: QrPuuSaKP4CQ5bg5jWaX0w-1 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 70CEC1955EE8; Tue, 22 Oct 2024 07:13:53 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.67.24.92]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B79E830001A3; Tue, 22 Oct 2024 07:13:49 +0000 (UTC) From: Ming-Hung Tsai To: dm-devel@lists.linux.dev Cc: mpatocka@redhat.com, thornber@redhat.com, heinzm@redhat.com, snitzer@kernel.org, Ming-Hung Tsai Subject: [PATCH 4/5] dm cache: optimize dirty bit checking with find_next_bit when resizing Date: Tue, 22 Oct 2024 15:13:39 +0800 Message-ID: <20241022071339.778721-1-mtsai@redhat.com> Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com When shrinking the fast device, dm-cache iteratively searches for a dirty bit among the cache blocks to be dropped, which is less efficient. Use find_next_bit instead, as it is twice as fast as the iterative approach with test_bit. Signed-off-by: Ming-Hung Tsai --- drivers/md/dm-cache-target.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1fcd8c5c220e..fa8ef2c32af8 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2911,14 +2911,14 @@ static bool can_resize(struct cache *cache, dm_cblock_t new_size) /* * We can't drop a dirty block when shrinking the cache. */ - while (from_cblock(new_size) < from_cblock(cache->cache_size)) { - if (is_dirty(cache, new_size)) { - DMERR("%s: unable to shrink cache; cache block %llu is dirty", - cache_device_name(cache), - (unsigned long long) from_cblock(new_size)); - return false; - } - new_size = to_cblock(from_cblock(new_size) + 1); + new_size = to_cblock(find_next_bit(cache->dirty_bitset, + from_cblock(cache->cache_size), + from_cblock(new_size))); + if (new_size != cache->cache_size) { + DMERR("%s: unable to shrink cache; cache block %llu is dirty", + cache_device_name(cache), + (unsigned long long) from_cblock(new_size)); + return false; } return true; From patchwork Tue Oct 22 07:13:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming-Hung Tsai X-Patchwork-Id: 13845230 X-Patchwork-Delegate: mpatocka@redhat.com Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 45BDA1494CE for ; Tue, 22 Oct 2024 07:14:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581259; cv=none; b=gqJ6lgFVrPl04HoIC/yMv/Iwn3R6ptXLivvuN4ejTuD5BFKVUrc8MbgLDtlWwXOWrKhsZ2sJ+M6R11ANEa+NpnbVca/S+S8vjiHxnxjnUzQHx+liO7w4sJz08Y0YwV4T1Ytp2ivlb+pd2sj8Q4Lm9fjWclHzwAJMMGFJBGr2vV0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729581259; c=relaxed/simple; bh=Q8ENeAkz48Y3VTR3Dq4JyHQdC/MhcnnpEPGIlvpUPdo=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=azwEkC8b776rfSt6kmHd5WyAdJoxUwDDteBllgn/cY7JO/OSaYdPsH7SW2E29g1E7p7S/y3w2cmh8zZhi+GRDe7+OZtYtQmSXcF6vQt9qwJo/3+oabTmztVap6GhldF2lnpcTrf2HFir/LHvJdj0a/L2PWxqC2Q1lwM/0iXc8GI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=MfUzMQzi; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="MfUzMQzi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1729581256; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vyrm88n/l7VkCAM9KVpNUNAT+MCV4oTA4h4H35isFR4=; b=MfUzMQzizLrlhWpg0jum1N8MyjQEFON/TgiU7iBYoayCrhJ4CmUpbYvfYm4s/BM0ZhXkzx HEyYCRdA9j675u9HbbI+t+nyBo9+vUArvMcsZnXPqekCwEvM2WVxR5RcFlzw5YpszGRJLx VLQyIRNI9+tM40vkSXGwsafEyouIhEE= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-439-40kV8SuRNnuJM90TMW7E0A-1; Tue, 22 Oct 2024 03:14:12 -0400 X-MC-Unique: 40kV8SuRNnuJM90TMW7E0A-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 191FD19560A2; Tue, 22 Oct 2024 07:14:12 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.67.24.92]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AA69C1955F39; Tue, 22 Oct 2024 07:14:08 +0000 (UTC) From: Ming-Hung Tsai To: dm-devel@lists.linux.dev Cc: mpatocka@redhat.com, thornber@redhat.com, heinzm@redhat.com, snitzer@kernel.org, Ming-Hung Tsai Subject: [PATCH 5/5] dm cache: fix potential out-of-bounds access on the first resume Date: Tue, 22 Oct 2024 15:13:54 +0800 Message-ID: <20241022071354.778749-1-mtsai@redhat.com> Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Out-of-bounds access occurs if the fast device is expanded unexpectedly before the first-time resume of the cache table. This happens because expanding the fast device requires reloading the cache table for cache_create to allocate new in-core data structures that fit the new size, and the check in cache_preresume is not performed during the first resume, leading to the issue. Reproduce steps: 1. prepare component devices: dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" dmsetup create corig --table "0 524288 linear /dev/sdc 262144" dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct 2. load a cache table of 512 cache blocks, and deliberately expand the fast device before resuming the cache, making the in-core data structures inadequate. dmsetup create cache --notable dmsetup reload cache --table "0 524288 cache /dev/mapper/cmeta \ /dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" dmsetup reload cdata --table "0 131072 linear /dev/sdc 8192" dmsetup resume cdata dmsetup resume cache 3. suspend the cache to write out the in-core dirty bitset and hint array, leading to out-of-bounds access to the dirty bitset at offset 0x40: dmsetup suspend cache KASAN reports: BUG: KASAN: vmalloc-out-of-bounds in is_dirty_callback+0x2b/0x80 Read of size 8 at addr ffffc90000085040 by task dmsetup/90 (...snip...) The buggy address belongs to the virtual mapping at [ffffc90000085000, ffffc90000087000) created by: cache_ctr+0x176a/0x35f0 (...snip...) Memory state around the buggy address: ffffc90000084f00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ffffc90000084f80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 >ffffc90000085000: 00 00 00 00 00 00 00 00 f8 f8 f8 f8 f8 f8 f8 f8 ^ ffffc90000085080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ffffc90000085100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 Fix by checking the size change on the first resume. Signed-off-by: Ming-Hung Tsai Fixes: f494a9c6b1b6 ("dm cache: cache shrinking support") --- drivers/md/dm-cache-target.c | 37 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index fa8ef2c32af8..40709310e327 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2901,24 +2901,24 @@ static dm_cblock_t get_cache_dev_size(struct cache *cache) static bool can_resize(struct cache *cache, dm_cblock_t new_size) { if (from_cblock(new_size) > from_cblock(cache->cache_size)) { - if (cache->sized) { - DMERR("%s: unable to extend cache due to missing cache table reload", - cache_device_name(cache)); - return false; - } + DMERR("%s: unable to extend cache due to missing cache table reload", + cache_device_name(cache)); + return false; } /* * We can't drop a dirty block when shrinking the cache. */ - new_size = to_cblock(find_next_bit(cache->dirty_bitset, - from_cblock(cache->cache_size), - from_cblock(new_size))); - if (new_size != cache->cache_size) { - DMERR("%s: unable to shrink cache; cache block %llu is dirty", - cache_device_name(cache), - (unsigned long long) from_cblock(new_size)); - return false; + if (cache->loaded_mappings) { + new_size = to_cblock(find_next_bit(cache->dirty_bitset, + from_cblock(cache->cache_size), + from_cblock(new_size))); + if (new_size != cache->cache_size) { + DMERR("%s: unable to shrink cache; cache block %llu is dirty", + cache_device_name(cache), + (unsigned long long) from_cblock(new_size)); + return false; + } } return true; @@ -2949,20 +2949,15 @@ static int cache_preresume(struct dm_target *ti) /* * Check to see if the cache has resized. */ - if (!cache->sized) { - r = resize_cache_dev(cache, csize); - if (r) - return r; - - cache->sized = true; - - } else if (csize != cache->cache_size) { + if (!cache->sized || csize != cache->cache_size) { if (!can_resize(cache, csize)) return -EINVAL; r = resize_cache_dev(cache, csize); if (r) return r; + + cache->sized = true; } if (!cache->loaded_mappings) {