From patchwork Thu Mar 19 12:33:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 1258258 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.com Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48jq0j3LqFz9sTN for ; Fri, 20 Mar 2020 01:24:21 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 047F781676; Thu, 19 Mar 2020 15:24:05 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 74B6681218; Thu, 19 Mar 2020 13:33:30 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 7BD7681286 for ; Thu, 19 Mar 2020 13:33:27 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=wqu@suse.com Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 45F56ACEF; Thu, 19 Mar 2020 12:33:27 +0000 (UTC) From: Qu Wenruo To: u-boot@lists.denx.de Cc: linux-btrfs@vger.kernel.org Subject: [PATCH 1/2] uboot: fs/btrfs: Use LZO_LEN to replace immediate number Date: Thu, 19 Mar 2020 20:33:18 +0800 Message-Id: <20200319123319.37848-2-wqu@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200319123319.37848-1-wqu@suse.com> References: <20200319123319.37848-1-wqu@suse.com> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 19 Mar 2020 15:23:58 +0100 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Just a cleanup. The immediate number makes my eye hurt. Signed-off-by: Qu Wenruo --- fs/btrfs/compression.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 346875d45a1b..4ef44ce11485 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -12,36 +12,38 @@ #include #include +/* Header for each segment, LE32, recording the compressed size */ +#define LZO_LEN 4 static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen) { u32 tot_len, in_len, res; size_t out_len; int ret; - if (clen < 4) + if (clen < LZO_LEN) return -1; tot_len = le32_to_cpu(get_unaligned((u32 *)cbuf)); - cbuf += 4; - clen -= 4; - tot_len -= 4; + cbuf += LZO_LEN; + clen -= LZO_LEN; + tot_len -= LZO_LEN; if (tot_len == 0 && dlen) return -1; - if (tot_len < 4) + if (tot_len < LZO_LEN) return -1; res = 0; - while (tot_len > 4) { + while (tot_len > LZO_LEN) { in_len = le32_to_cpu(get_unaligned((u32 *)cbuf)); - cbuf += 4; - clen -= 4; + cbuf += LZO_LEN; + clen -= LZO_LEN; - if (in_len > clen || tot_len < 4 + in_len) + if (in_len > clen || tot_len < LZO_LEN + in_len) return -1; - tot_len -= 4 + in_len; + tot_len -= (LZO_LEN + in_len); out_len = dlen; ret = lzo1x_decompress_safe(cbuf, in_len, dbuf, &out_len); From patchwork Thu Mar 19 12:33:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 1258259 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.com Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48jq0t2jNMz9sTN for ; Fri, 20 Mar 2020 01:24:29 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8124B81737; Thu, 19 Mar 2020 15:24:07 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 5178981552; Thu, 19 Mar 2020 13:33:37 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id E416681286 for ; Thu, 19 Mar 2020 13:33:33 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=wqu@suse.com Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id B2D5DAD72; Thu, 19 Mar 2020 12:33:33 +0000 (UTC) From: Qu Wenruo To: u-boot@lists.denx.de Cc: linux-btrfs@vger.kernel.org Subject: [PATCH 2/2] uboot: fs/btrfs: Fix LZO false decompression error caused by pending zero Date: Thu, 19 Mar 2020 20:33:19 +0800 Message-Id: <20200319123319.37848-3-wqu@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200319123319.37848-1-wqu@suse.com> References: <20200319123319.37848-1-wqu@suse.com> MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 19 Mar 2020 15:23:58 +0100 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean [BUG] For certain btrfs files with compressed file extent, uboot will fail to load it: btrfs_read_extent_reg: disk_bytenr=14229504 disk_len=73728 offset=0 nr_bytes=131 072 decompress_lzo: tot_len=70770 decompress_lzo: in_len=1389 decompress_lzo: in_len=2400 decompress_lzo: in_len=3002 decompress_lzo: in_len=1379 decompress_lzo: in_len=88539136 decompress_lzo: header error, in_len=88539136 clen=65534 tot_len=62580 NOTE: except the last line, all other lines are debug output. [CAUSE] Btrfs lzo compression uses its own format to record compressed size (segmant header, LE32). However to make decompression easier, we never put such segment header across page boundary. In above case, the xxd dump of the lzo compressed data looks like this: 00001fe0: 4cdc 02fc 0bfd 02c0 dc02 0d13 0100 0001 L............... 00001ff0: 0000 0008 0300 0000 0000 0011 0000|0000 ................ 00002000: 4705 0000 0001 cc02 0000 0000 0000 1e01 G............... '|' is the "expected" segment header start position. But in that page, there are only 2 bytes left, can't contain the 4 bytes segment header. So btrfs compression will skip that 2 bytes, put the segment header in next page directly. Uboot doesn't have such check, and read the header with 2 bytes offset, result 0x05470000 (88539136), other than the expected result 0x00000547 (1351), resulting above error. [FIX] Follow the btrfs-progs restore implementation, by introducing tot_in to record total processed bytes (including headers), and do proper page boundary skip to fix it. Signed-off-by: Qu Wenruo --- fs/btrfs/compression.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 4ef44ce11485..2a6ac8bb1029 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,7 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen) { u32 tot_len, in_len, res; + u32 tot_in = 0; size_t out_len; int ret; @@ -27,6 +29,7 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen) cbuf += LZO_LEN; clen -= LZO_LEN; tot_len -= LZO_LEN; + tot_in += LZO_LEN; if (tot_len == 0 && dlen) return -1; @@ -36,6 +39,9 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen) res = 0; while (tot_len > LZO_LEN) { + size_t mod_page; + size_t rem_page; + in_len = le32_to_cpu(get_unaligned((u32 *)cbuf)); cbuf += LZO_LEN; clen -= LZO_LEN; @@ -44,6 +50,7 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen) return -1; tot_len -= (LZO_LEN + in_len); + tot_in += (LZO_LEN + in_len); out_len = dlen; ret = lzo1x_decompress_safe(cbuf, in_len, dbuf, &out_len); @@ -56,6 +63,19 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen) dlen -= out_len; res += out_len; + + /* + * If the 4 bytes header does not fit to the rest of the page we + * have to move to next one, or we read some garbage. + */ + mod_page = tot_in % PAGE_SIZE; + rem_page = PAGE_SIZE - mod_page; + if (rem_page < LZO_LEN) { + cbuf += rem_page; + tot_in += rem_page; + clen -= rem_page; + tot_len -= rem_page; + } } return res;