From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B859F1A0B0A; Sun, 28 Jul 2024 00:55:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722128159; cv=none; b=GOm8LKDw4jQTdlRTnT3LHhjryEEh0Z507qfM6a921+HEcTS9Q1neakXf74S97jTTUG5IeTPmNvm38L+uipyrAo6pQ6FvJ7C7C+8O9rpS4aW+3pWBFmhQRXV37ox0X2WBMiAkOpss3kLL99dnZCPHgoXjsqhbdJ0rv5v0RCdK+pc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722128159; c=relaxed/simple; bh=kFevJLBujr1xQ5pThVVFKbQjVbolhn003MqkEybtqMY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hPDF0NLwSPUzS4Lpsdqx1T4T8rfVL3GJrfpWSYvvKyl2BAvp6l1eGCBn9XyM03D+MVd/bOEkMybr2Lj0qxoiDHz9RgUAZSdg/Abj/pT3ePEY+7ftNo9774fmGT61MyDE5byTSE7v9R14AR3SOxe9P25H0QPKRuy12kf+ZNRPDdk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pEq2J6pV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pEq2J6pV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71130C4AF0B; Sun, 28 Jul 2024 00:55:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722128159; bh=kFevJLBujr1xQ5pThVVFKbQjVbolhn003MqkEybtqMY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pEq2J6pVWn7Kz6K1hxsd+vb+sX7Hse5Vq/mt26u7UGUcRJYiP03uG3Pdcnfbgk2C6 7nvzL1mh82j/W3Kg0af238vAaBJLXYFESu1I1ooferPvgwxO5BfRe5KVR+fFuKMNTH dLbXtcqIaAlhzeHi5u47lLxqZW9OBKcrwnRLS+Hx2aRjNinBoDqih4EuCqtWl3yeBD xw9KSUY14InCmPGFHOEn4o1Eg4yYpc2KuvlIyAYnO87hGt0d8zYWeVvzccI6cuaNg8 nHOd8bwL/1/6PREy2JZ3mP7xbwrvaxi+GYrB9rUy5bVBuJr1r25vXF9T9dMjxcUpoQ vNyXmSPm5a+JQ== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Roman Smirnov , Jan Kara , Jan Kara , Sasha Levin Subject: [PATCH AUTOSEL 5.15 4/6] udf: prevent integer overflow in udf_bitmap_free_blocks() Date: Sat, 27 Jul 2024 20:55:45 -0400 Message-ID: <20240728005549.1734443-4-sashal@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240728005549.1734443-1-sashal@kernel.org> References: <20240728005549.1734443-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 5.15.164 Content-Transfer-Encoding: 8bit From: Roman Smirnov [ Upstream commit 56e69e59751d20993f243fb7dd6991c4e522424c ] An overflow may occur if the function is called with the last block and an offset greater than zero. It is necessary to add a check to avoid this. Found by Linux Verification Center (linuxtesting.org) with Svace. [JK: Make test cover also unalloc table freeing] Link: https://patch.msgid.link/20240620072413.7448-1-r.smirnov@omp.ru Suggested-by: Jan Kara Signed-off-by: Roman Smirnov Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/udf/balloc.c | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index f416b7fe092fc..aeaa6d1f0e015 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -22,6 +22,7 @@ #include "udfdecl.h" #include +#include #include "udf_i.h" #include "udf_sb.h" @@ -133,7 +134,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb, { struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = NULL; - struct udf_part_map *partmap; unsigned long block; unsigned long block_group; unsigned long bit; @@ -142,19 +142,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb, unsigned long overflow; mutex_lock(&sbi->s_alloc_mutex); - partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; - if (bloc->logicalBlockNum + count < count || - (bloc->logicalBlockNum + count) > partmap->s_partition_len) { - udf_debug("%u < %d || %u + %u > %u\n", - bloc->logicalBlockNum, 0, - bloc->logicalBlockNum, count, - partmap->s_partition_len); - goto error_return; - } - + /* We make sure this cannot overflow when mounting the filesystem */ block = bloc->logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3); - do { overflow = 0; block_group = block >> (sb->s_blocksize_bits + 3); @@ -384,7 +374,6 @@ static void udf_table_free_blocks(struct super_block *sb, uint32_t count) { struct udf_sb_info *sbi = UDF_SB(sb); - struct udf_part_map *partmap; uint32_t start, end; uint32_t elen; struct kernel_lb_addr eloc; @@ -393,16 +382,6 @@ static void udf_table_free_blocks(struct super_block *sb, struct udf_inode_info *iinfo; mutex_lock(&sbi->s_alloc_mutex); - partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; - if (bloc->logicalBlockNum + count < count || - (bloc->logicalBlockNum + count) > partmap->s_partition_len) { - udf_debug("%u < %d || %u + %u > %u\n", - bloc->logicalBlockNum, 0, - bloc->logicalBlockNum, count, - partmap->s_partition_len); - goto error_return; - } - iinfo = UDF_I(table); udf_add_free_space(sb, sbi->s_partition, count); @@ -677,6 +656,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode, { uint16_t partition = bloc->partitionReferenceNum; struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; + uint32_t blk; + + if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) || + check_add_overflow(blk, count, &blk) || + bloc->logicalBlockNum + count > map->s_partition_len) { + udf_debug("Invalid request to free blocks: (%d, %u), off %u, " + "len %u, partition len %u\n", + partition, bloc->logicalBlockNum, offset, count, + map->s_partition_len); + return; + } if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, -- 2.43.0