1 | From: Sheng Yong <shengyong1@xiaomi.com> | 1 | From: Sheng Yong <shengyong1@xiaomi.com> |
---|---|---|---|
2 | 2 | ||
3 | When testing EROFS file-backed mount over v9fs on qemu, I encounter | 3 | When testing EROFS file-backed mount over v9fs on qemu, I encountered |
4 | a folio UAF and page sanity check reports the following call trace. | 4 | a folio UAF issue. The page sanity check reports the following call |
5 | Fix it by increasing non slab folio refcount correctly. | 5 | trace. The root cause is that pages in bvec are coalesced across a folio |
6 | bounary. The refcount of all non-slab folios should be increased to | ||
7 | ensure p9_releas_pages can put them correctly. | ||
6 | 8 | ||
7 | BUG: Bad page state in process md5sum pfn:18300 | 9 | BUG: Bad page state in process md5sum pfn:18300 |
8 | page: refcount:0 mapcount:0 mapping:00000000d5ad8e4e index:0x60 pfn:0x18300 | 10 | page: refcount:0 mapcount:0 mapping:00000000d5ad8e4e index:0x60 pfn:0x18300 |
9 | head: order:0 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 | 11 | head: order:0 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 |
10 | aops:z_erofs_aops ino:30b0f dentry name(?):"GoogleExtServicesCn.apk" | 12 | aops:z_erofs_aops ino:30b0f dentry name(?):"GoogleExtServicesCn.apk" |
... | ... | ||
44 | entry_SYSCALL_64_after_hwframe+0x71/0x79 | 46 | entry_SYSCALL_64_after_hwframe+0x71/0x79 |
45 | 47 | ||
46 | Fixes: b9c0e49abfca ("mm: decline to manipulate the refcount on a slab page") | 48 | Fixes: b9c0e49abfca ("mm: decline to manipulate the refcount on a slab page") |
47 | Signed-off-by: Sheng Yong <shengyong1@xiaomi.com> | 49 | Signed-off-by: Sheng Yong <shengyong1@xiaomi.com> |
48 | --- | 50 | --- |
49 | lib/iov_iter.c | 3 +-- | 51 | lib/iov_iter.c | 2 +- |
50 | 1 file changed, 1 insertion(+), 2 deletions(-) | 52 | 1 file changed, 1 insertion(+), 1 deletion(-) |
53 | --- | ||
54 | v2: | ||
55 | * update commit message | ||
56 | * update coding style | ||
51 | 57 | ||
52 | diff --git a/lib/iov_iter.c b/lib/iov_iter.c | 58 | diff --git a/lib/iov_iter.c b/lib/iov_iter.c |
53 | index XXXXXXX..XXXXXXX 100644 | 59 | index XXXXXXX..XXXXXXX 100644 |
54 | --- a/lib/iov_iter.c | 60 | --- a/lib/iov_iter.c |
55 | +++ b/lib/iov_iter.c | 61 | +++ b/lib/iov_iter.c |
56 | @@ -XXX,XX +XXX,XX @@ static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i, | 62 | @@ -XXX,XX +XXX,XX @@ static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i, |
57 | return -ENOMEM; | 63 | return -ENOMEM; |
58 | p = *pages; | 64 | p = *pages; |
59 | for (int k = 0; k < n; k++) { | 65 | for (int k = 0; k < n; k++) { |
60 | - struct folio *folio = page_folio(page); | 66 | - struct folio *folio = page_folio(page); |
61 | - p[k] = page + k; | 67 | + struct folio *folio = page_folio(page + k); |
62 | + struct folio *folio = page_folio(p[k] = page + k); | 68 | p[k] = page + k; |
63 | if (!folio_test_slab(folio)) | 69 | if (!folio_test_slab(folio)) |
64 | folio_get(folio); | 70 | folio_get(folio); |
65 | } | ||
66 | -- | 71 | -- |
67 | 2.43.0 | 72 | 2.43.0 | diff view generated by jsdifflib |