Commit f9a7b4ad authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Put fixmaps into /proc/pid/maps via a pseudo-vma

From: David Mosberger <davidm@napali.hpl.hp.com>

This patch makes /proc/PID/maps report the range from FIXADDR_USER_START to
FIXADDR_USER_END as a final pseudo-vma.  This is consistent with the notion
that reading /proc/PID/maps tells you about every page containing data that
the process can in fact access, and with things such as ptrace allowing
access to this memory.  Without this, userland tools that want to look at all
of a process's accessible pages need special-case knowledge about things such
as the vsyscall DSO page.  With this change, existing code that iterates over
the /proc/PID/maps lines will cover those pages like any other.  For example,
this lets gdb's "gcore" command synthesize a core file from a live process
that contains the vsyscall DSO page as a real core dump would, using its
existing generic iterator code and no new special cases.
parent 8976f5f6
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <asm/elf.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
char *task_mem(struct mm_struct *mm, char *buffer) char *task_mem(struct mm_struct *mm, char *buffer)
...@@ -75,6 +76,22 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, ...@@ -75,6 +76,22 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
return size; return size;
} }
#ifdef AT_SYSINFO_EHDR
static struct vm_area_struct gate_vmarea = {
/* Do _not_ mark this area as readable, cuz not the entire range may be readable
(e.g., due to execute-only pages or holes) and the tools that read
/proc/PID/maps should read the interesting bits from the gate-DSO file
instead. */
.vm_start = FIXADDR_USER_START,
.vm_end = FIXADDR_USER_END
};
# define gate_map() &gate_vmarea
#else
# define gate_map() NULL
#endif
static int show_map(struct seq_file *m, void *v) static int show_map(struct seq_file *m, void *v)
{ {
struct vm_area_struct *map = v; struct vm_area_struct *map = v;
...@@ -128,6 +145,8 @@ static void *m_start(struct seq_file *m, loff_t *pos) ...@@ -128,6 +145,8 @@ static void *m_start(struct seq_file *m, loff_t *pos)
if (!map) { if (!map) {
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
mmput(mm); mmput(mm);
if (l == -1)
map = gate_map();
} }
return map; return map;
} }
...@@ -135,7 +154,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) ...@@ -135,7 +154,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
static void m_stop(struct seq_file *m, void *v) static void m_stop(struct seq_file *m, void *v)
{ {
struct vm_area_struct *map = v; struct vm_area_struct *map = v;
if (map) { if (map && map != gate_map()) {
struct mm_struct *mm = map->vm_mm; struct mm_struct *mm = map->vm_mm;
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
mmput(mm); mmput(mm);
...@@ -149,6 +168,8 @@ static void *m_next(struct seq_file *m, void *v, loff_t *pos) ...@@ -149,6 +168,8 @@ static void *m_next(struct seq_file *m, void *v, loff_t *pos)
if (map->vm_next) if (map->vm_next)
return map->vm_next; return map->vm_next;
m_stop(m, v); m_stop(m, v);
if (map != gate_map())
return gate_map();
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment