]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
erofs: fix out-of-bound read for shifted uncompressed block
authorGao Xiang <gaoxiang25@huawei.com>
Tue, 7 Jan 2020 02:25:46 +0000 (10:25 +0800)
committerGao Xiang <gaoxiang25@huawei.com>
Sat, 11 Jan 2020 10:29:19 +0000 (18:29 +0800)
rq->out[1] should be valid before accessing. Otherwise,
in very rare cases, out-of-bound dirty onstack rq->out[1]
can equal to *in and lead to unintended memmove behavior.

Link: https://lore.kernel.org/r/20200107022546.19432-1-gaoxiang25@huawei.com
Fixes: 7fc45dbc938a ("staging: erofs: introduce generic decompression backend")
Cc: <stable@vger.kernel.org> # 5.3+
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
fs/erofs/decompressor.c

index 2890a67a1ded61d4eca977c64a3b19eb8319b801..5779a15c2cd6f23beca10b3d1a5a98a893480c73 100644 (file)
@@ -306,24 +306,22 @@ static int z_erofs_shifted_transform(const struct z_erofs_decompress_req *rq,
        }
 
        src = kmap_atomic(*rq->in);
-       if (!rq->out[0]) {
-               dst = NULL;
-       } else {
+       if (rq->out[0]) {
                dst = kmap_atomic(rq->out[0]);
                memcpy(dst + rq->pageofs_out, src, righthalf);
+               kunmap_atomic(dst);
        }
 
-       if (rq->out[1] == *rq->in) {
-               memmove(src, src + righthalf, rq->pageofs_out);
-       } else if (nrpages_out == 2) {
-               if (dst)
-                       kunmap_atomic(dst);
+       if (nrpages_out == 2) {
                DBG_BUGON(!rq->out[1]);
-               dst = kmap_atomic(rq->out[1]);
-               memcpy(dst, src + righthalf, rq->pageofs_out);
+               if (rq->out[1] == *rq->in) {
+                       memmove(src, src + righthalf, rq->pageofs_out);
+               } else {
+                       dst = kmap_atomic(rq->out[1]);
+                       memcpy(dst, src + righthalf, rq->pageofs_out);
+                       kunmap_atomic(dst);
+               }
        }
-       if (dst)
-               kunmap_atomic(dst);
        kunmap_atomic(src);
        return 0;
 }