All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Lasse Collin <lasse.collin@tukaani.org>,
	Gao Xiang <hsiangkao@linux.alibaba.com>,
	Sasha Levin <sashal@kernel.org>,
	thunder.leizhen@huawei.com, akpm@linux-foundation.org,
	gustavoars@kernel.org, ojeda@kernel.org, ndesaulniers@google.com
Subject: [PATCH AUTOSEL 4.14 26/39] lib/xz: Avoid overlapping memcpy() with invalid input with in-place decompression
Date: Mon,  8 Nov 2021 20:06:36 -0500	[thread overview]
Message-ID: <20211109010649.1191041-26-sashal@kernel.org> (raw)
In-Reply-To: <20211109010649.1191041-1-sashal@kernel.org>

From: Lasse Collin <lasse.collin@tukaani.org>

[ Upstream commit 83d3c4f22a36d005b55f44628f46cc0d319a75e8 ]

With valid files, the safety margin described in lib/decompress_unxz.c
ensures that these buffers cannot overlap. But if the uncompressed size
of the input is larger than the caller thought, which is possible when
the input file is invalid/corrupt, the buffers can overlap. Obviously
the result will then be garbage (and usually the decoder will return
an error too) but no other harm will happen when such an over-run occurs.

This change only affects uncompressed LZMA2 chunks and so this
should have no effect on performance.

Link: https://lore.kernel.org/r/20211010213145.17462-2-xiang@kernel.org
Signed-off-by: Lasse Collin <lasse.collin@tukaani.org>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 lib/decompress_unxz.c |  2 +-
 lib/xz/xz_dec_lzma2.c | 21 +++++++++++++++++++--
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c
index 25d59a95bd668..abea25310ac73 100644
--- a/lib/decompress_unxz.c
+++ b/lib/decompress_unxz.c
@@ -167,7 +167,7 @@
  * memeq and memzero are not used much and any remotely sane implementation
  * is fast enough. memcpy/memmove speed matters in multi-call mode, but
  * the kernel image is decompressed in single-call mode, in which only
- * memcpy speed can matter and only if there is a lot of uncompressible data
+ * memmove speed can matter and only if there is a lot of uncompressible data
  * (LZMA2 stores uncompressible chunks in uncompressed form). Thus, the
  * functions below should just be kept small; it's probably not worth
  * optimizing for speed.
diff --git a/lib/xz/xz_dec_lzma2.c b/lib/xz/xz_dec_lzma2.c
index 08c3c80499983..2c5197d6b944d 100644
--- a/lib/xz/xz_dec_lzma2.c
+++ b/lib/xz/xz_dec_lzma2.c
@@ -387,7 +387,14 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
 
 		*left -= copy_size;
 
-		memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
+		/*
+		 * If doing in-place decompression in single-call mode and the
+		 * uncompressed size of the file is larger than the caller
+		 * thought (i.e. it is invalid input!), the buffers below may
+		 * overlap and cause undefined behavior with memcpy().
+		 * With valid inputs memcpy() would be fine here.
+		 */
+		memmove(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
 		dict->pos += copy_size;
 
 		if (dict->full < dict->pos)
@@ -397,7 +404,11 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
 			if (dict->pos == dict->end)
 				dict->pos = 0;
 
-			memcpy(b->out + b->out_pos, b->in + b->in_pos,
+			/*
+			 * Like above but for multi-call mode: use memmove()
+			 * to avoid undefined behavior with invalid input.
+			 */
+			memmove(b->out + b->out_pos, b->in + b->in_pos,
 					copy_size);
 		}
 
@@ -421,6 +432,12 @@ static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
 		if (dict->pos == dict->end)
 			dict->pos = 0;
 
+		/*
+		 * These buffers cannot overlap even if doing in-place
+		 * decompression because in multi-call mode dict->buf
+		 * has been allocated by us in this file; it's not
+		 * provided by the caller like in single-call mode.
+		 */
 		memcpy(b->out + b->out_pos, dict->buf + dict->start,
 				copy_size);
 	}
-- 
2.33.0


  parent reply	other threads:[~2021-11-09  1:20 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-09  1:06 [PATCH AUTOSEL 4.14 01/39] Bluetooth: sco: Fix lock_sock() blockage by memcpy_from_msg() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 02/39] Bluetooth: fix use-after-free error in lock_sock_nested() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 03/39] platform/x86: wmi: do not fail if disabling fails Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 04/39] MIPS: lantiq: dma: add small delay after reset Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 05/39] MIPS: lantiq: dma: reset correct number of channel Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 06/39] locking/lockdep: Avoid RCU-induced noinstr fail Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 07/39] smackfs: Fix use-after-free in netlbl_catmap_walk() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 08/39] NET: IPV4: fix error "do not initialise globals to 0" Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 09/39] x86: Increase exception stack sizes Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 10/39] mwifiex: Run SET_BSS_MODE when changing from P2P to STATION vif-type Sasha Levin
2021-11-09 18:06   ` Brian Norris
2021-11-14 14:03     ` Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 11/39] mwifiex: Properly initialize private structure on interface type changes Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 12/39] media: mt9p031: Fix corrupted frame after restarting stream Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 13/39] media: netup_unidvb: handle interrupt properly according to the firmware Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 14/39] media: uvcvideo: Set capability in s_param Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 15/39] media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe() Sasha Levin
2021-11-09  1:06   ` Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 16/39] media: s5p-mfc: Add checking to s5p_mfc_probe() Sasha Levin
2021-11-09  1:06   ` Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 17/39] media: mceusb: return without resubmitting URB in case of -EPROTO error Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 18/39] ia64: don't do IA64_CMPXCHG_DEBUG without CONFIG_PRINTK Sasha Levin
2021-11-09  1:06   ` Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 19/39] ACPICA: Avoid evaluating methods too early during system resume Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 20/39] media: usb: dvd-usb: fix uninit-value bug in dibusb_read_eeprom_byte() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 21/39] tracefs: Have tracefs directories not set OTH permission bits by default Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 22/39] ath: dfs_pattern_detector: Fix possible null-pointer dereference in channel_detector_create() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 23/39] ACPI: battery: Accept charges over the design capacity as full Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 24/39] leaking_addresses: Always print a trailing newline Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 25/39] memstick: r592: Fix a UAF bug when removing the driver Sasha Levin
2021-11-09  1:06 ` Sasha Levin [this message]
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 27/39] lib/xz: Validate the value before assigning it to an enum variable Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 28/39] tracing/cfi: Fix cmp_entries_* functions signature mismatch Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 29/39] mwl8k: Fix use-after-free in mwl8k_fw_state_machine() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 30/39] PM: hibernate: Get block device exclusively in swsusp_check() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 31/39] iwlwifi: mvm: disable RX-diversity in powersave Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 32/39] smackfs: use __GFP_NOFAIL for smk_cipso_doi() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 33/39] ARM: clang: Do not rely on lr register for stacktrace Sasha Levin
2021-11-09  1:06   ` Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 34/39] gre/sit: Don't generate link-local addr if addr_gen_mode is IN6_ADDR_GEN_MODE_NONE Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 35/39] ARM: 9136/1: ARMv7-M uses BE-8, not BE-32 Sasha Levin
2021-11-09  1:06   ` Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 36/39] spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in bcm_qspi_probe() Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 37/39] parisc: fix warning in flush_tlb_all Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 38/39] task_stack: Fix end_of_stack() for architectures with upwards-growing stack Sasha Levin
2021-11-09  1:06 ` [PATCH AUTOSEL 4.14 39/39] parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling 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=20211109010649.1191041-26-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=gustavoars@kernel.org \
    --cc=hsiangkao@linux.alibaba.com \
    --cc=lasse.collin@tukaani.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=ojeda@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=thunder.leizhen@huawei.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.