]>
Commit | Line | Data |
---|---|---|
1fc1caab GKH |
1 | From 1e5ceeab6929585512c63d05911d6657064abf7b Mon Sep 17 00:00:00 2001 |
2 | From: Gao Xiang <gaoxiang25@huawei.com> | |
3 | Date: Wed, 27 Feb 2019 13:33:31 +0800 | |
4 | Subject: staging: erofs: fix illegal address access under memory pressure | |
5 | ||
6 | From: Gao Xiang <gaoxiang25@huawei.com> | |
7 | ||
8 | commit 1e5ceeab6929585512c63d05911d6657064abf7b upstream. | |
9 | ||
10 | Considering a read request with two decompressed file pages, | |
11 | If a decompression work cannot be started on the previous page | |
12 | due to memory pressure but in-memory LTP map lookup is done, | |
13 | builder->work should be still NULL. | |
14 | ||
15 | Moreover, if the current page also belongs to the same map, | |
16 | it won't try to start the decompression work again and then | |
17 | run into trouble. | |
18 | ||
19 | This patch aims to solve the above issue only with little changes | |
20 | as much as possible in order to make the fix backport easier. | |
21 | ||
22 | kernel message is: | |
23 | <4>[1051408.015930s]SLUB: Unable to allocate memory on node -1, gfp=0x2408040(GFP_NOFS|__GFP_ZERO) | |
24 | <4>[1051408.015930s] cache: erofs_compress, object size: 144, buffer size: 144, default order: 0, min order: 0 | |
25 | <4>[1051408.015930s] node 0: slabs: 98, objs: 2744, free: 0 | |
26 | * Cannot allocate the decompression work | |
27 | ||
28 | <3>[1051408.015960s]erofs: z_erofs_vle_normalaccess_readpages, readahead error at page 1008 of nid 5391488 | |
29 | * Note that the previous page was failed to read | |
30 | ||
31 | <0>[1051408.015960s]Internal error: Accessing user space memory outside uaccess.h routines: 96000005 [#1] PREEMPT SMP | |
32 | ... | |
33 | <4>[1051408.015991s]Hardware name: kirin710 (DT) | |
34 | ... | |
35 | <4>[1051408.016021s]PC is at z_erofs_vle_work_add_page+0xa0/0x17c | |
36 | <4>[1051408.016021s]LR is at z_erofs_do_read_page+0x12c/0xcf0 | |
37 | ... | |
38 | <4>[1051408.018096s][<ffffff80c6fb0fd4>] z_erofs_vle_work_add_page+0xa0/0x17c | |
39 | <4>[1051408.018096s][<ffffff80c6fb3814>] z_erofs_vle_normalaccess_readpages+0x1a0/0x37c | |
40 | <4>[1051408.018096s][<ffffff80c6d670b8>] read_pages+0x70/0x190 | |
41 | <4>[1051408.018127s][<ffffff80c6d6736c>] __do_page_cache_readahead+0x194/0x1a8 | |
42 | <4>[1051408.018127s][<ffffff80c6d59318>] filemap_fault+0x398/0x684 | |
43 | <4>[1051408.018127s][<ffffff80c6d8a9e0>] __do_fault+0x8c/0x138 | |
44 | <4>[1051408.018127s][<ffffff80c6d8f90c>] handle_pte_fault+0x730/0xb7c | |
45 | <4>[1051408.018127s][<ffffff80c6d8fe04>] __handle_mm_fault+0xac/0xf4 | |
46 | <4>[1051408.018157s][<ffffff80c6d8fec8>] handle_mm_fault+0x7c/0x118 | |
47 | <4>[1051408.018157s][<ffffff80c8c52998>] do_page_fault+0x354/0x474 | |
48 | <4>[1051408.018157s][<ffffff80c8c52af8>] do_translation_fault+0x40/0x48 | |
49 | <4>[1051408.018157s][<ffffff80c6c002f4>] do_mem_abort+0x80/0x100 | |
50 | <4>[1051408.018310s]---[ end trace 9f4009a3283bd78b ]--- | |
51 | ||
52 | Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") | |
53 | Cc: <stable@vger.kernel.org> # 4.19+ | |
54 | Signed-off-by: Gao Xiang <gaoxiang25@huawei.com> | |
55 | Reviewed-by: Chao Yu <yuchao0@huawei.com> | |
56 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
57 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
58 | ||
59 | --- | |
60 | drivers/staging/erofs/unzip_vle.c | 7 ++++++- | |
61 | 1 file changed, 6 insertions(+), 1 deletion(-) | |
62 | ||
63 | --- a/drivers/staging/erofs/unzip_vle.c | |
64 | +++ b/drivers/staging/erofs/unzip_vle.c | |
65 | @@ -721,8 +721,12 @@ repeat: | |
66 | ||
67 | /* lucky, within the range of the current map_blocks */ | |
68 | if (offset + cur >= map->m_la && | |
69 | - offset + cur < map->m_la + map->m_llen) | |
70 | + offset + cur < map->m_la + map->m_llen) { | |
71 | + /* didn't get a valid unzip work previously (very rare) */ | |
72 | + if (!builder->work) | |
73 | + goto restart_now; | |
74 | goto hitted; | |
75 | + } | |
76 | ||
77 | /* go ahead the next map_blocks */ | |
78 | debugln("%s: [out-of-range] pos %llu", __func__, offset + cur); | |
79 | @@ -736,6 +740,7 @@ repeat: | |
80 | if (unlikely(err)) | |
81 | goto err_out; | |
82 | ||
83 | +restart_now: | |
84 | if (unlikely(!(map->m_flags & EROFS_MAP_MAPPED))) | |
85 | goto hitted; | |
86 |