From: Luo Xinqiang <luoxinqia...@huawei.com>

In function scatterwalk_pagedone(), a kernel panic of invalid
page will occur if walk->offset equals 0. This patch fixes the
problem by setting the page addresswith sg_page(walk->sg)
directly if walk->offset equals 0.

Panic call stack:
[<ffffff9632b4f418>] blkcipher_walk_done+0x430/0x8dc
[<ffffff9632b4ed50>] blkcipher_walk_next+0x750/0x9e8
[<ffffff9632b4fe08>] blkcipher_walk_first+0x110/0x2c0
[<ffffff9632b50084>] blkcipher_walk_virt+0xcc/0xe0
[<ffffff96324b3680>] cbc_decrypt+0xdc/0x1a8
[<ffffff9632ba3f90>] ablk_decrypt+0x138/0x224
[<ffffff9632b50a90>] skcipher_decrypt_ablkcipher+0x130/0x150
[<ffffff9632b9d6d4>] skcipher_recvmsg_sync.isra.17+0x270/0x404
[<ffffff9632b9d900>] skcipher_recvmsg+0x98/0xb8
[<ffffff9634044908>] SyS_recvfrom+0x2ac/0x2fc
[<ffffff96324839c0>] el0_svc_naked+0x34/0x38

Test: do syskaller fuzz test on 4.9 & 4.4

Signed-off-by: Gao Kui <gaok...@huawei.com>
Signed-off-by: Luo Xinqiang <luoxinqia...@huawei.com>
---
 crypto/scatterwalk.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index bc769c4..a265907 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -53,7 +53,11 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, 
int out,
        if (out) {
                struct page *page;
 
-               page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
+               if (likely(walk->offset))
+                       page = sg_page(walk->sg) +
+                               ((walk->offset - 1) >> PAGE_SHIFT);
+               else
+                       page = sg_page(walk->sg);
                /* Test ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE first as
                 * PageSlab cannot be optimised away per se due to
                 * use of volatile pointer.
-- 
2.7.4

Reply via email to