Commit 30e13e41 authored by Gao Xiang's avatar Gao Xiang
Browse files

erofs: enable error reporting for z_erofs_fixup_insize()



Enable propagation of detailed errors to callers.

Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent 3a991f78
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -72,8 +72,8 @@ struct z_erofs_stream_dctx {

const char *z_erofs_stream_switch_bufs(struct z_erofs_stream_dctx *dctx,
				void **dst, void **src, struct page **pgpl);
int z_erofs_fixup_insize(struct z_erofs_decompress_req *rq, const char *padbuf,
			 unsigned int padbufsize);
const char *z_erofs_fixup_insize(struct z_erofs_decompress_req *rq,
				 const char *padbuf, unsigned int padbufsize);
int __init z_erofs_init_decompressor(void);
void z_erofs_exit_decompressor(void);
int z_erofs_crypto_decompress(struct z_erofs_decompress_req *rq,
+11 −10
Original line number Diff line number Diff line
@@ -178,21 +178,21 @@ static void *z_erofs_lz4_handle_overlap(const struct z_erofs_decompress_req *rq,
}

/*
 * Get the exact inputsize with zero_padding feature.
 *  - For LZ4, it should work if zero_padding feature is on (5.3+);
 *  - For MicroLZMA, it'd be enabled all the time.
 * Get the exact on-disk size of the compressed data:
 *  - For LZ4, it should apply if the zero_padding feature is on (5.3+);
 *  - For others, zero_padding is enabled all the time.
 */
int z_erofs_fixup_insize(struct z_erofs_decompress_req *rq, const char *padbuf,
			 unsigned int padbufsize)
const char *z_erofs_fixup_insize(struct z_erofs_decompress_req *rq,
				 const char *padbuf, unsigned int padbufsize)
{
	const char *padend;

	padend = memchr_inv(padbuf, 0, padbufsize);
	if (!padend)
		return -EFSCORRUPTED;
		return "compressed data start not found";
	rq->inputsize -= padend - padbuf;
	rq->pageofs_in += padend - padbuf;
	return 0;
	return NULL;
}

static int z_erofs_lz4_decompress_mem(struct z_erofs_decompress_req *rq, u8 *dst)
@@ -200,6 +200,7 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_decompress_req *rq, u8 *dst
	bool support_0padding = false, may_inplace = false;
	unsigned int inputmargin;
	u8 *out, *headpage, *src;
	const char *reason;
	int ret, maptype;

	DBG_BUGON(*rq->in == NULL);
@@ -208,12 +209,12 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_decompress_req *rq, u8 *dst
	/* LZ4 decompression inplace is only safe if zero_padding is enabled */
	if (erofs_sb_has_zero_padding(EROFS_SB(rq->sb))) {
		support_0padding = true;
		ret = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in,
		reason = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in,
				min_t(unsigned int, rq->inputsize,
				      rq->sb->s_blocksize - rq->pageofs_in));
		if (ret) {
		if (reason) {
			kunmap_local(headpage);
			return ret;
			return IS_ERR(reason) ? PTR_ERR(reason) : -EFSCORRUPTED;
		}
		may_inplace = !((rq->pageofs_in + rq->inputsize) &
				(rq->sb->s_blocksize - 1));
+4 −3
Original line number Diff line number Diff line
@@ -9,16 +9,17 @@ static int __z_erofs_crypto_decompress(struct z_erofs_decompress_req *rq,
	struct sg_table st_src, st_dst;
	struct acomp_req *req;
	struct crypto_wait wait;
	const char *reason;
	u8 *headpage;
	int ret;

	headpage = kmap_local_page(*rq->in);
	ret = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in,
	reason = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in,
				min_t(unsigned int, rq->inputsize,
				      rq->sb->s_blocksize - rq->pageofs_in));
	kunmap_local(headpage);
	if (ret)
		return ret;
	if (reason)
		return IS_ERR(reason) ? PTR_ERR(reason) : -EFSCORRUPTED;

	req = acomp_request_alloc(tfm);
	if (!req)
+9 −10
Original line number Diff line number Diff line
@@ -103,16 +103,16 @@ static const char *__z_erofs_deflate_decompress(struct z_erofs_decompress_req *r
	struct super_block *sb = rq->sb;
	struct z_erofs_stream_dctx dctx = { .rq = rq, .no = -1, .ni = 0 };
	struct z_erofs_deflate *strm;
	const char *reason = NULL;
	int zerr, err;
	const char *reason;
	int zerr;

	/* 1. get the exact DEFLATE compressed size */
	dctx.kin = kmap_local_page(*rq->in);
	err = z_erofs_fixup_insize(rq, dctx.kin + rq->pageofs_in,
	reason = z_erofs_fixup_insize(rq, dctx.kin + rq->pageofs_in,
			min(rq->inputsize, sb->s_blocksize - rq->pageofs_in));
	if (err) {
	if (reason) {
		kunmap_local(dctx.kin);
		return ERR_PTR(err);
		return reason;
	}

	/* 2. get an available DEFLATE context */
@@ -130,7 +130,7 @@ static const char *__z_erofs_deflate_decompress(struct z_erofs_decompress_req *r
	/* 3. multi-call decompress */
	zerr = zlib_inflateInit2(&strm->z, -MAX_WBITS);
	if (zerr != Z_OK) {
		err = -EINVAL;
		reason = ERR_PTR(-EINVAL);
		goto failed_zinit;
	}

@@ -161,12 +161,11 @@ static const char *__z_erofs_deflate_decompress(struct z_erofs_decompress_req *r
			reason = (zerr == Z_DATA_ERROR ?
				"corrupted compressed data" :
				"unexpected end of stream");
			err = -EFSCORRUPTED;
			break;
		}
	}
	if (zlib_inflateEnd(&strm->z) != Z_OK && !err)
		err = -EIO;
	if (zlib_inflateEnd(&strm->z) != Z_OK && !reason)
		reason = ERR_PTR(-EIO);
	if (dctx.kout)
		kunmap_local(dctx.kout);
failed_zinit:
@@ -177,7 +176,7 @@ static const char *__z_erofs_deflate_decompress(struct z_erofs_decompress_req *r
	z_erofs_deflate_head = strm;
	spin_unlock(&z_erofs_deflate_lock);
	wake_up(&z_erofs_deflate_wq);
	return reason ?: ERR_PTR(err);
	return reason;
}

static const char *z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
+5 −6
Original line number Diff line number Diff line
@@ -154,16 +154,15 @@ static const char *z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
	struct xz_buf buf = {};
	struct z_erofs_lzma *strm;
	enum xz_ret xz_err;
	const char *reason = NULL;
	int err;
	const char *reason;

	/* 1. get the exact LZMA compressed size */
	dctx.kin = kmap_local_page(*rq->in);
	err = z_erofs_fixup_insize(rq, dctx.kin + rq->pageofs_in,
	reason = z_erofs_fixup_insize(rq, dctx.kin + rq->pageofs_in,
			min(rq->inputsize, sb->s_blocksize - rq->pageofs_in));
	if (err) {
	if (reason) {
		kunmap_local(dctx.kin);
		return ERR_PTR(err);
		return reason;
	}

	/* 2. get an available lzma context */
@@ -224,7 +223,7 @@ static const char *z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
	z_erofs_lzma_head = strm;
	spin_unlock(&z_erofs_lzma_lock);
	wake_up(&z_erofs_lzma_wq);
	return reason ?: ERR_PTR(err);
	return reason;
}

const struct z_erofs_decompressor z_erofs_lzma_decomp = {
Loading