busybox: backport fix for CVE-2021-28831
This backports a fix for the low priority CVE-2021-28831: decompress_gunzip.c in BusyBox through 1.32.1 mishandles the error bit on the huft_build result pointer, with a resultant invalid free or segmentation fault, via malformed gzip data. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
		| @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk | |||||||
|  |  | ||||||
| PKG_NAME:=busybox | PKG_NAME:=busybox | ||||||
| PKG_VERSION:=1.33.0 | PKG_VERSION:=1.33.0 | ||||||
| PKG_RELEASE:=2 | PKG_RELEASE:=3 | ||||||
| PKG_FLAGS:=essential | PKG_FLAGS:=essential | ||||||
|  |  | ||||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 | ||||||
|   | |||||||
| @@ -0,0 +1,52 @@ | |||||||
|  | From f25d254dfd4243698c31a4f3153d4ac72aa9e9bd Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Samuel Sapalski <samuel.sapalski@nokia.com> | ||||||
|  | Date: Wed, 3 Mar 2021 16:31:22 +0100 | ||||||
|  | Subject: decompress_gunzip: Fix DoS if gzip is corrupt | ||||||
|  |  | ||||||
|  | On certain corrupt gzip files, huft_build will set the error bit on | ||||||
|  | the result pointer. If afterwards abort_unzip is called huft_free | ||||||
|  | might run into a segmentation fault or an invalid pointer to | ||||||
|  | free(p). | ||||||
|  |  | ||||||
|  | In order to mitigate this, we check in huft_free if the error bit | ||||||
|  | is set and clear it before the linked list is freed. | ||||||
|  |  | ||||||
|  | Signed-off-by: Samuel Sapalski <samuel.sapalski@nokia.com> | ||||||
|  | Signed-off-by: Peter Kaestle <peter.kaestle@nokia.com> | ||||||
|  | Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> | ||||||
|  | --- | ||||||
|  |  archival/libarchive/decompress_gunzip.c | 12 ++++++++++-- | ||||||
|  |  1 file changed, 10 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/archival/libarchive/decompress_gunzip.c | ||||||
|  | +++ b/archival/libarchive/decompress_gunzip.c | ||||||
|  | @@ -220,10 +220,20 @@ static const uint8_t border[] ALIGN1 = { | ||||||
|  |   * each table. | ||||||
|  |   * t: table to free | ||||||
|  |   */ | ||||||
|  | +#define BAD_HUFT(p) ((uintptr_t)(p) & 1) | ||||||
|  | +#define ERR_RET     ((huft_t*)(uintptr_t)1) | ||||||
|  |  static void huft_free(huft_t *p) | ||||||
|  |  { | ||||||
|  |  	huft_t *q; | ||||||
|  |   | ||||||
|  | +	/* | ||||||
|  | +	 * If 'p' has the error bit set we have to clear it, otherwise we might run | ||||||
|  | +	 * into a segmentation fault or an invalid pointer to free(p) | ||||||
|  | +	 */ | ||||||
|  | +	if (BAD_HUFT(p)) { | ||||||
|  | +		p = (huft_t*)((uintptr_t)(p) ^ (uintptr_t)(ERR_RET)); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	/* Go through linked list, freeing from the malloced (t[-1]) address. */ | ||||||
|  |  	while (p) { | ||||||
|  |  		q = (--p)->v.t; | ||||||
|  | @@ -289,8 +299,6 @@ static unsigned fill_bitbuffer(STATE_PAR | ||||||
|  |   * or a valid pointer to a Huffman table, ORed with 0x1 if incompete table | ||||||
|  |   * is given: "fixed inflate" decoder feeds us such data. | ||||||
|  |   */ | ||||||
|  | -#define BAD_HUFT(p) ((uintptr_t)(p) & 1) | ||||||
|  | -#define ERR_RET     ((huft_t*)(uintptr_t)1) | ||||||
|  |  static huft_t* huft_build(const unsigned *b, const unsigned n, | ||||||
|  |  			const unsigned s, const struct cp_ext *cp_ext, | ||||||
|  |  			unsigned *m) | ||||||
		Reference in New Issue
	
	Block a user
	 Hauke Mehrtens
					Hauke Mehrtens