On 2022/7/6 11:21, Matthew Wilcox wrote:
On Wed, Jul 06, 2022 at 11:24:34AM +0800, Liu Shixin wrote:
Release refcount after xas_set to fix UAF which may cause panic like this:
I think we can do better. How about this?
Thank you for your idea, it looks more concise.
diff --git a/mm/filemap.c b/mm/filemap.c index 00e391e75880..11ae38cc4fd3 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2090,7 +2090,9 @@ unsigned find_lock_entries(struct address_space *mapping, pgoff_t start, rcu_read_lock(); while ((page = find_get_entry(&xas, end, XA_PRESENT))) {
if (!xa_is_value(page)) {unsigned long next_idx = xas.xa_index + 1;
next_idx = page->index + thp_nr_pages(page); if (page->index < start) goto put; if (page->index + thp_nr_pages(page) - 1 > end)
@@ -2111,14 +2113,11 @@ unsigned find_lock_entries(struct address_space *mapping, pgoff_t start, put: put_page(page); next:
if (!xa_is_value(page) && PageTransHuge(page)) {
unsigned int nr_pages = thp_nr_pages(page);
/* Final THP may cross MAX_LFS_FILESIZE on 32-bit */
xas_set(&xas, page->index + nr_pages);
if (xas.xa_index < nr_pages)
break;
}
/* Final THP may cross MAX_LFS_FILESIZE on 32-bit */
if (next_idx < xas.xa_index)
break;
if (next_idx != xas.xa_index + 1)
} rcu_read_unlock();xas_set(&xas, next_idx);
.