aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2018-06-07 20:07:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-07 20:34:36 -0400
commitab6ecf247a9321e3180e021a6a60164dee53ab2e (patch)
tree38799d423d5a69a3295aeb94887d96e2e20cf5e7
parent25cf23d7a95716fc6eb165208b5eb2e3b2e86f82 (diff)
mm: /proc/pid/pagemap: hide swap entries from unprivileged users
In commit ab676b7d6fbf ("pagemap: do not leak physical addresses to non-privileged userspace"), the /proc/PID/pagemap is restricted to be readable only by CAP_SYS_ADMIN to address some security issue. In commit 1c90308e7a77 ("pagemap: hide physical addresses from non-privileged users"), the restriction is relieved to make /proc/PID/pagemap readable, but hide the physical addresses for non-privileged users. But the swap entries are readable for non-privileged users too. This has some security issues. For example, for page under migrating, the swap entry has physical address information. So, in this patch, the swap entries are hided for non-privileged users too. Link: http://lkml.kernel.org/r/20180508012745.7238-1-ying.huang@intel.com Fixes: 1c90308e7a77 ("pagemap: hide physical addresses from non-privileged users") Signed-off-by: "Huang, Ying" <ying.huang@intel.com> Suggested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Reviewed-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Cc: Andrei Vagin <avagin@openvz.org> Cc: Jerome Glisse <jglisse@redhat.com> Cc: Daniel Colascione <dancol@google.com> Cc: Zi Yan <zi.yan@cs.rutgers.edu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/proc/task_mmu.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 7e074138d2f2..597969db9e90 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -1259,8 +1259,9 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm,
1259 if (pte_swp_soft_dirty(pte)) 1259 if (pte_swp_soft_dirty(pte))
1260 flags |= PM_SOFT_DIRTY; 1260 flags |= PM_SOFT_DIRTY;
1261 entry = pte_to_swp_entry(pte); 1261 entry = pte_to_swp_entry(pte);
1262 frame = swp_type(entry) | 1262 if (pm->show_pfn)
1263 (swp_offset(entry) << MAX_SWAPFILES_SHIFT); 1263 frame = swp_type(entry) |
1264 (swp_offset(entry) << MAX_SWAPFILES_SHIFT);
1264 flags |= PM_SWAP; 1265 flags |= PM_SWAP;
1265 if (is_migration_entry(entry)) 1266 if (is_migration_entry(entry))
1266 page = migration_entry_to_page(entry); 1267 page = migration_entry_to_page(entry);
@@ -1311,11 +1312,14 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
1311#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION 1312#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
1312 else if (is_swap_pmd(pmd)) { 1313 else if (is_swap_pmd(pmd)) {
1313 swp_entry_t entry = pmd_to_swp_entry(pmd); 1314 swp_entry_t entry = pmd_to_swp_entry(pmd);
1314 unsigned long offset = swp_offset(entry); 1315 unsigned long offset;
1315 1316
1316 offset += (addr & ~PMD_MASK) >> PAGE_SHIFT; 1317 if (pm->show_pfn) {
1317 frame = swp_type(entry) | 1318 offset = swp_offset(entry) +
1318 (offset << MAX_SWAPFILES_SHIFT); 1319 ((addr & ~PMD_MASK) >> PAGE_SHIFT);
1320 frame = swp_type(entry) |
1321 (offset << MAX_SWAPFILES_SHIFT);
1322 }
1319 flags |= PM_SWAP; 1323 flags |= PM_SWAP;
1320 if (pmd_swp_soft_dirty(pmd)) 1324 if (pmd_swp_soft_dirty(pmd))
1321 flags |= PM_SOFT_DIRTY; 1325 flags |= PM_SOFT_DIRTY;
@@ -1333,10 +1337,12 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
1333 err = add_to_pagemap(addr, &pme, pm); 1337 err = add_to_pagemap(addr, &pme, pm);
1334 if (err) 1338 if (err)
1335 break; 1339 break;
1336 if (pm->show_pfn && (flags & PM_PRESENT)) 1340 if (pm->show_pfn) {
1337 frame++; 1341 if (flags & PM_PRESENT)
1338 else if (flags & PM_SWAP) 1342 frame++;
1339 frame += (1 << MAX_SWAPFILES_SHIFT); 1343 else if (flags & PM_SWAP)
1344 frame += (1 << MAX_SWAPFILES_SHIFT);
1345 }
1340 } 1346 }
1341 spin_unlock(ptl); 1347 spin_unlock(ptl);
1342 return err; 1348 return err;