`fuzz_erofsfsck` reports a heap-buffer-overflow issue.

Reproducible image (base64-encoded gzipped blob):
H4sICEI5WmgCA2Vyb2ZzZnNja19saWJmdXp6ZXJfdVhJS1BnAGNkAIKu////M8ABIwMDO8NA
AA6iVSqQYCoTkepWMQwDwIPGFxhUrvv/nx+fNDUdizMFs1DdV9vpHc5MVDHlN5h89PDrg/1G
87YxgxOPigcs3KSXrUsH0ReXSWLoNMASlo8eQMzhgJgDDP8usDNVEEouLuMElS1AwHeRESq2
iZn9N4NNtzOXVqL1bNf7CTO2RkIM/c8KpvqJBFiSGrBI+0FRIUPNhP+F4SGIdiBeC0aK+kFE
8WlMIqBnGDQMZIVBTuEEzhoG8KwBKlJGkzDNk7ABPmBpZGBqYmpoYgZMu+amxgbmBhbU8R1f
JDw+2YAYFJ3g2Jxxze3Cxog9oNZRCitS7cJEXJ2Dz8P7KWlvAAAOXVIStwkAAA==

Add a `rq->decodedlength > rq->inputsize` check to match the kernel
implementation for now.

Closes: https://github.com/erofs/erofs-utils/issues/20
Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com>
---
 lib/decompress.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/decompress.c b/lib/decompress.c
index 1e9fad7..3e7a173 100644
--- a/lib/decompress.c
+++ b/lib/decompress.c
@@ -514,14 +514,13 @@ int z_erofs_decompress(struct z_erofs_decompress_req *rq)
        if (rq->alg == Z_EROFS_COMPRESSION_INTERLACED) {
                unsigned int count, rightpart, skip;
 
-               /* XXX: should support inputsize >= erofs_blksiz(sbi) later */
-               if (rq->inputsize > erofs_blksiz(sbi))
-                       return -EFSCORRUPTED;
-
-               if (rq->decodedlength > erofs_blksiz(sbi))
+               if (rq->decodedlength > rq->inputsize)
+                       return -EOPNOTSUPP;
+               if (rq->decodedlength < rq->decodedskip)
                        return -EFSCORRUPTED;
 
-               if (rq->decodedlength < rq->decodedskip)
+               /* XXX: should support inputsize >= erofs_blksiz(sbi) later */
+               if (rq->inputsize > erofs_blksiz(sbi))
                        return -EFSCORRUPTED;
 
                count = rq->decodedlength - rq->decodedskip;
@@ -532,9 +531,10 @@ int z_erofs_decompress(struct z_erofs_decompress_req *rq)
                return 0;
        } else if (rq->alg == Z_EROFS_COMPRESSION_SHIFTED) {
                if (rq->decodedlength > rq->inputsize)
+                       return -EOPNOTSUPP;
+               if (rq->decodedlength < rq->decodedskip)
                        return -EFSCORRUPTED;
 
-               DBG_BUGON(rq->decodedlength < rq->decodedskip);
                memcpy(rq->out, rq->in + rq->decodedskip,
                       rq->decodedlength - rq->decodedskip);
                return 0;
-- 
2.43.5


Reply via email to