diff options
author | 2020-06-16 13:31:47 +0200 | |
---|---|---|
committer | 2020-06-16 13:31:47 +0200 | |
commit | 4b3c1f1b15f576445c221cbc77a88540433a2ba7 (patch) | |
tree | b88ac114c16fa1747205c9060bf00498bcb5df97 /mm/debug.c | |
parent | drm/ttm: Fix dma_fence refcnt leak when adding move fence (diff) | |
parent | Linux 5.8-rc1 (diff) | |
download | wireguard-linux-4b3c1f1b15f576445c221cbc77a88540433a2ba7.tar.xz wireguard-linux-4b3c1f1b15f576445c221cbc77a88540433a2ba7.zip |
Merge v5.8-rc1 into drm-misc-fixes
Beginning a new release cycles for what will become v5.8. Updating
drm-misc-fixes accordingly.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Diffstat (limited to 'mm/debug.c')
-rw-r--r-- | mm/debug.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/mm/debug.c b/mm/debug.c index 2189357f0987..b5b1de8c71ac 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -110,13 +110,57 @@ void __dump_page(struct page *page, const char *reason) else if (PageAnon(page)) type = "anon "; else if (mapping) { - if (mapping->host && mapping->host->i_dentry.first) { - struct dentry *dentry; - dentry = container_of(mapping->host->i_dentry.first, struct dentry, d_u.d_alias); - pr_warn("%ps name:\"%pd\"\n", mapping->a_ops, dentry); - } else - pr_warn("%ps\n", mapping->a_ops); + const struct inode *host; + const struct address_space_operations *a_ops; + const struct hlist_node *dentry_first; + const struct dentry *dentry_ptr; + struct dentry dentry; + + /* + * mapping can be invalid pointer and we don't want to crash + * accessing it, so probe everything depending on it carefully + */ + if (probe_kernel_read(&host, &mapping->host, + sizeof(struct inode *)) || + probe_kernel_read(&a_ops, &mapping->a_ops, + sizeof(struct address_space_operations *))) { + pr_warn("failed to read mapping->host or a_ops, mapping not a valid kernel address?\n"); + goto out_mapping; + } + + if (!host) { + pr_warn("mapping->a_ops:%ps\n", a_ops); + goto out_mapping; + } + + if (probe_kernel_read(&dentry_first, + &host->i_dentry.first, sizeof(struct hlist_node *))) { + pr_warn("mapping->a_ops:%ps with invalid mapping->host inode address %px\n", + a_ops, host); + goto out_mapping; + } + + if (!dentry_first) { + pr_warn("mapping->a_ops:%ps\n", a_ops); + goto out_mapping; + } + + dentry_ptr = container_of(dentry_first, struct dentry, d_u.d_alias); + if (probe_kernel_read(&dentry, dentry_ptr, + sizeof(struct dentry))) { + pr_warn("mapping->aops:%ps with invalid mapping->host->i_dentry.first %px\n", + a_ops, dentry_ptr); + } else { + /* + * if dentry is corrupted, the %pd handler may still + * crash, but it's unlikely that we reach here with a + * corrupted struct page + */ + pr_warn("mapping->aops:%ps dentry name:\"%pd\"\n", + a_ops, &dentry); + } } +out_mapping: BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS + 1); pr_warn("%sflags: %#lx(%pGp)%s\n", type, page->flags, &page->flags, |