From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Nick Terrell <terrelln@fb.com>, Vasily Gorbik <gor@linux.ibm.com>,
Heiko Carstens <hca@linux.ibm.com>,
Sasha Levin <sashal@kernel.org>, Yann Collet <cyan@fb.com>,
gaoxin@cdjrlc.com
Subject: [PATCH AUTOSEL 6.2 08/45] lib: zstd: Backport fix for in-place decompression
Date: Wed, 22 Mar 2023 15:56:02 -0400 [thread overview]
Message-ID: <20230322195639.1995821-8-sashal@kernel.org> (raw)
In-Reply-To: <20230322195639.1995821-1-sashal@kernel.org>
From: Nick Terrell <terrelln@fb.com>
[ Upstream commit 038505c41f0aad26ef101f4f7f6e111531c3914f ]
Backport the relevant part of upstream commit 5b266196 [0].
This fixes in-place decompression for x86-64 kernel decompression. It
uses a bound of 131072 + (uncompressed_size >> 8), which can be violated
after upstream commit 6a7ede3d [1], as zstd can use part of the output
buffer as temporary storage, and without this patch needs a bound of
~262144.
The fix is for zstd to detect that the input and output buffers overlap,
so that zstd knows it can't use the overlapping portion of the output
buffer as tempoary storage. If the margin is not large enough, this will
ensure that zstd will fail the decompression, rather than overwriting
part of the input data, and causing corruption.
This fix has been landed upstream and is in release v1.5.4. That commit
also adds unit and fuzz tests to verify that the margin we use is
respected, and correct. That means that the fix is well tested upstream.
I have not been able to reproduce the potential bug in x86-64 kernel
decompression locally, nor have I recieved reports of failures to
decompress the kernel. It is possible that compression saves enough
space to make it very hard for the issue to appear.
I've boot tested the zstd compressed kernel on x86-64 and i386 with this
patch, which uses in-place decompression, and sanity tested zstd compression
in btrfs / squashfs to make sure that we don't see any issues, but other
uses of zstd shouldn't be affected, because they don't use in-place
decompression.
Thanks to Vasily Gorbik <gor@linux.ibm.com> for debugging a related issue
on s390, which was triggered by the same commit, but was a bug in how
__decompress() was called [2]. And to Sasha Levin <sashal@kernel.org>
for the CC alerting me of the issue.
[0] https://github.com/facebook/zstd/commit/5b266196a41e6a15e21bd4f0eeab43b938db1d90
[1] https://github.com/facebook/zstd/commit/6a7ede3dfccbf3e0a5928b4224a039c260dcff72
[2] https://lore.kernel.org/r/patch-1.thread-41c676.git-41c676c2d153.your-ad-here.call-01675030179-ext-9637@work.hours
CC: Vasily Gorbik <gor@linux.ibm.com>
CC: Heiko Carstens <hca@linux.ibm.com>
CC: Sasha Levin <sashal@kernel.org>
CC: Yann Collet <cyan@fb.com>
Signed-off-by: Nick Terrell <terrelln@fb.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/zstd/decompress/zstd_decompress.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/lib/zstd/decompress/zstd_decompress.c b/lib/zstd/decompress/zstd_decompress.c
index b9b935a9f5c0d..6b3177c947114 100644
--- a/lib/zstd/decompress/zstd_decompress.c
+++ b/lib/zstd/decompress/zstd_decompress.c
@@ -798,7 +798,7 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
if (srcSize == 0) return 0;
RETURN_ERROR(dstBuffer_null, "");
}
- ZSTD_memcpy(dst, src, srcSize);
+ ZSTD_memmove(dst, src, srcSize);
return srcSize;
}
@@ -858,6 +858,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
/* Loop on each block */
while (1) {
+ BYTE* oBlockEnd = oend;
size_t decodedSize;
blockProperties_t blockProperties;
size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
@@ -867,16 +868,34 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
remainingSrcSize -= ZSTD_blockHeaderSize;
RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
+ if (ip >= op && ip < oBlockEnd) {
+ /* We are decompressing in-place. Limit the output pointer so that we
+ * don't overwrite the block that we are currently reading. This will
+ * fail decompression if the input & output pointers aren't spaced
+ * far enough apart.
+ *
+ * This is important to set, even when the pointers are far enough
+ * apart, because ZSTD_decompressBlock_internal() can decide to store
+ * literals in the output buffer, after the block it is decompressing.
+ * Since we don't want anything to overwrite our input, we have to tell
+ * ZSTD_decompressBlock_internal to never write past ip.
+ *
+ * See ZSTD_allocateLiteralsBuffer() for reference.
+ */
+ oBlockEnd = op + (ip - op);
+ }
+
switch(blockProperties.blockType)
{
case bt_compressed:
- decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1, not_streaming);
+ decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, /* frame */ 1, not_streaming);
break;
case bt_raw :
+ /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */
decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
break;
case bt_rle :
- decodedSize = ZSTD_setRleBlock(op, (size_t)(oend-op), *ip, blockProperties.origSize);
+ decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize);
break;
case bt_reserved :
default:
--
2.39.2
next prev parent reply other threads:[~2023-03-22 19:59 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-22 19:55 [PATCH AUTOSEL 6.2 01/45] xfrm: Zero padding when dumping algos and encap Sasha Levin
2023-03-22 19:55 ` [PATCH AUTOSEL 6.2 02/45] ASoC: codecs: tx-macro: Fix for KASAN: slab-out-of-bounds Sasha Levin
2023-03-22 19:55 ` [PATCH AUTOSEL 6.2 03/45] ASoC: Intel: avs: max98357a: Explicitly define codec format Sasha Levin
2023-03-22 19:55 ` [PATCH AUTOSEL 6.2 04/45] ASoC: Intel: avs: da7219: " Sasha Levin
2023-03-22 19:55 ` [PATCH AUTOSEL 6.2 05/45] ASoC: Intel: avs: rt5682: " Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 06/45] ASoC: Intel: avs: ssm4567: Remove nau8825 bits Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 07/45] ASoC: Intel: avs: nau8825: Adjust clock control Sasha Levin
2023-03-22 19:56 ` Sasha Levin [this message]
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 09/45] zstd: Fix definition of assert() Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 10/45] ACPI: video: Add backlight=native DMI quirk for Dell Vostro 15 3535 Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 11/45] ACPI: x86: Introduce an acpi_quirk_skip_gpio_event_handlers() helper Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 12/45] ACPI: x86: Add skip i2c clients quirk for Acer Iconia One 7 B1-750 Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 13/45] ACPI: x86: Add skip i2c clients quirk for Lenovo Yoga Book X90 Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 14/45] ASoC: SOF: ipc3: Check for upper size limit for the received message Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 15/45] ASoC: SOF: ipc4-topology: Fix incorrect sample rate print unit Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 16/45] ASoC: SOF: Intel: pci-tng: revert invalid bar size setting Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 17/45] ASoC: SOF: Intel: hda-dsp: harden D0i3 programming sequence Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 18/45] ASoC: SOF: Intel: hda-ctrl: re-add sleep after entering and exiting reset Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 19/45] ASoC: SOF: IPC4: update gain ipc msg definition to align with fw Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 20/45] ASoC: hdmi-codec: only startup/shutdown on supported streams Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 21/45] wifi: mac80211: check basic rates validity Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 22/45] md: avoid signed overflow in slot_store() Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 23/45] x86/PVH: obtain VGA console info in Dom0 Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 24/45] drm/amdkfd: Fix BO offset for multi-VMA page migration Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 25/45] drm/amdkfd: fix a potential double free in pqm_create_queue Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 26/45] drm/amdgpu/vcn: custom video info caps for sriov Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 27/45] drm/amdkfd: fix potential kgd_mem UAFs Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 28/45] drm/amd/display: Fix HDCP failing to enable after suspend Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 29/45] net: hsr: Don't log netdev_err message on unknown prp dst node Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 30/45] ALSA: asihpi: check pao in control_message() Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 31/45] ALSA: hda/ca0132: fixup buffer overrun at tuning_ctl_set() Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 32/45] fbdev: tgafb: Fix potential divide by zero Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 33/45] ACPI: tools: pfrut: Check if the input of level and type is in the right numeric range Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 34/45] sched_getaffinity: don't assume 'cpumask_size()' is fully initialized Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 35/45] nvme-pci: fixing memory leak in probe teardown path Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 36/45] nvme-pci: add NVME_QUIRK_BOGUS_NID for Lexar NM620 Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 37/45] drm/amdkfd: Fixed kfd_process cleanup on module exit Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 38/45] net/mlx5e: Lower maximum allowed MTU in XSK to match XDP prerequisites Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 39/45] fbdev: nvidia: Fix potential divide by zero Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 40/45] fbdev: intelfb: " Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 41/45] fbdev: lxfb: " Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 42/45] fbdev: au1200fb: " Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 43/45] tools/power turbostat: Fix /dev/cpu_dma_latency warnings Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 44/45] tools/power turbostat: fix decoding of HWP_STATUS Sasha Levin
2023-03-22 19:56 ` [PATCH AUTOSEL 6.2 45/45] tracing: Fix wrong return in kprobe_event_gen_test.c Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230322195639.1995821-8-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=cyan@fb.com \
--cc=gaoxin@cdjrlc.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=terrelln@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®