2004-06-24 10:51:20

by Roland McGrath

[permalink] [raw]
Subject: [PATCH] fix x86-64 ptrace access to 32-bit vsyscall page

When I made get_user_pages support looking up a pte for the "gate" area, I
assumed it would be part of the kernel's fixed mappings. On x86-64 running
a 32-bit task, the 32-bit vsyscall DSO page still has no vma but has its
pte allocated in the user mm in the normal fashion. This patch makes it
use the generic page-table lookup calls rather than the shortcuts.
With this, ptrace on x86-64 can access a 32-bit process's vsyscall page.
The behavior on x86 is unchanged.

Signed-off-by: Roland McGrath <[email protected]>


Thanks,
Roland


Index: linux-2.6/mm/memory.c
===================================================================
RCS file: /home/roland/redhat/bkcvs/linux-2.5/mm/memory.c,v
retrieving revision 1.172
diff -p -u -r1.172 memory.c
--- linux-2.6/mm/memory.c 5 Jun 2004 17:52:06 -0000 1.172
+++ linux-2.6/mm/memory.c 24 Jun 2004 10:37:12 -0000
@@ -718,19 +718,24 @@ int get_user_pages(struct task_struct *t
pte_t *pte;
if (write) /* user gate pages are read-only */
return i ? : -EFAULT;
- pgd = pgd_offset_k(pg);
+ pgd = pgd_offset(mm, pg);
if (!pgd)
return i ? : -EFAULT;
pmd = pmd_offset(pgd, pg);
if (!pmd)
return i ? : -EFAULT;
- pte = pte_offset_kernel(pmd, pg);
- if (!pte || !pte_present(*pte))
+ pte = pte_offset_map(pmd, pg);
+ if (!pte)
return i ? : -EFAULT;
+ if (!pte_present(*pte)) {
+ pte_unmap(pte);
+ return i ? : -EFAULT;
+ }
if (pages) {
pages[i] = pte_page(*pte);
get_page(pages[i]);
}
+ pte_unmap(pte);
if (vmas)
vmas[i] = gate_vma;
i++;