mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
New function to check if the page is readable before reading. Noop on
Sat Apr 23 17:49:33 2005 Søren Sandmann <sandmann@redhat.com> * sysprof-module.c (page_readable): New function to check if the page is readable before reading. Noop on kernel <= 2.6.11 * sysprof-module.c (get_mm, put_mm): New functions to confine #ifdefs.
This commit is contained in:
committed by
Søren Sandmann Pedersen
parent
7b67e2c6b9
commit
753eb9378b
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
Sat Apr 23 17:49:33 2005 Søren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* sysprof-module.c (page_readable): New function to check if the
|
||||||
|
page is readable before reading. Noop on kernel <= 2.6.11
|
||||||
|
|
||||||
|
* sysprof-module.c (get_mm, put_mm): New functions to confine
|
||||||
|
#ifdefs.
|
||||||
|
|
||||||
|
Sat Apr 23 17:48:22 2005 Søren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* Makefile (MODCFLAGS): Disable optimization as I suspect
|
||||||
|
the oops is related to miscompilation.
|
||||||
|
|
||||||
Fri Apr 22 00:09:16 2005 Soeren Sandmann <sandmann@redhat.com>
|
Fri Apr 22 00:09:16 2005 Soeren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
* sysprof-module.c (read_user_space): On >= 2.6.11 check that the
|
* sysprof-module.c (read_user_space): On >= 2.6.11 check that the
|
||||||
|
|||||||
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ BINARY := sysprof
|
|||||||
MODULE := sysprof-module
|
MODULE := sysprof-module
|
||||||
KDIR := /lib/modules/$(shell uname -r)/build
|
KDIR := /lib/modules/$(shell uname -r)/build
|
||||||
INCLUDE := -isystem $(KDIR)/include
|
INCLUDE := -isystem $(KDIR)/include
|
||||||
MODCFLAGS := -O2 -DMODULE -D__KERNEL__ -Wall ${INCLUDE}
|
MODCFLAGS := -DMODULE -D__KERNEL__ -Wall ${INCLUDE}
|
||||||
MODULE := sysprof-module
|
MODULE := sysprof-module
|
||||||
|
|
||||||
all: check $(BINARY) $(MODULE).o
|
all: check $(BINARY) $(MODULE).o
|
||||||
|
|||||||
@ -72,29 +72,50 @@ struct userspace_reader
|
|||||||
* Source/target buffer must be kernel space,
|
* Source/target buffer must be kernel space,
|
||||||
* Do not walk the page table directly, use get_user_pages
|
* Do not walk the page table directly, use get_user_pages
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static struct mm_struct *
|
||||||
|
get_mm (struct task_struct *tsk)
|
||||||
|
{
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
|
||||||
|
struct mm_struct *mm;
|
||||||
|
|
||||||
|
task_lock (tsk);
|
||||||
|
mm = tsk->mm;
|
||||||
|
task_unlock (tsk);
|
||||||
|
|
||||||
|
return mm;
|
||||||
|
#else
|
||||||
|
return get_task_mm (tsk);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_mm (struct mm_struct *mm)
|
||||||
|
{
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
|
||||||
|
mmput(mm);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
x_access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
|
x_access_process_vm (struct task_struct *tsk,
|
||||||
|
unsigned long addr,
|
||||||
|
void *buf, int len, int write)
|
||||||
{
|
{
|
||||||
struct mm_struct *mm;
|
struct mm_struct *mm;
|
||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
void *old_buf = buf;
|
void *old_buf = buf;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
|
mm = get_mm (tsk);
|
||||||
task_lock (tsk);
|
|
||||||
mm = tsk->mm;
|
|
||||||
task_unlock (tsk);
|
|
||||||
#else
|
|
||||||
mm = get_task_mm (tsk);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!mm)
|
if (!mm)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
down_read(&mm->mmap_sem);
|
down_read(&mm->mmap_sem);
|
||||||
/* ignore errors, just check how much was sucessfully transfered */
|
/* ignore errors, just check how much was sucessfully transfered */
|
||||||
while (len) {
|
while (len)
|
||||||
|
{
|
||||||
int bytes, ret, offset;
|
int bytes, ret, offset;
|
||||||
void *maddr;
|
void *maddr;
|
||||||
|
|
||||||
@ -131,9 +152,7 @@ x_access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int
|
|||||||
}
|
}
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
|
put_mm (mm);
|
||||||
mmput(mm);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return buf - old_buf;
|
return buf - old_buf;
|
||||||
}
|
}
|
||||||
@ -150,6 +169,27 @@ init_userspace_reader (userspace_reader *reader,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
page_readable (userspace_reader *reader, unsigned long address)
|
||||||
|
{
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION (2,6,11)
|
||||||
|
struct mm_struct *mm;
|
||||||
|
int result = 1;
|
||||||
|
|
||||||
|
mm = get_mm (reader->task);
|
||||||
|
|
||||||
|
if (!mm)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!check_user_page_readable (reader->task->mm, address))
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
put_mm (mm);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_user_space (userspace_reader *reader,
|
read_user_space (userspace_reader *reader,
|
||||||
unsigned long address,
|
unsigned long address,
|
||||||
@ -158,11 +198,10 @@ read_user_space (userspace_reader *reader,
|
|||||||
unsigned long cache_address = reader->cache_address;
|
unsigned long cache_address = reader->cache_address;
|
||||||
int index, r;
|
int index, r;
|
||||||
|
|
||||||
if (!cache_address || cache_address != (address & PAGE_MASK)) {
|
if (!cache_address || cache_address != (address & PAGE_MASK))
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION (2,6,11)
|
{
|
||||||
if (!check_user_page_readable (reader->task->mm, address))
|
if (!page_readable (reader, address))
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
cache_address = address & PAGE_MASK;
|
cache_address = address & PAGE_MASK;
|
||||||
|
|
||||||
@ -240,7 +279,7 @@ generate_stack_trace(struct task_struct *task,
|
|||||||
if (init_userspace_reader (&reader, task))
|
if (init_userspace_reader (&reader, task))
|
||||||
{
|
{
|
||||||
while (i < SYSPROF_MAX_ADDRESSES &&
|
while (i < SYSPROF_MAX_ADDRESSES &&
|
||||||
read_frame (&reader, addr, &frame) &&
|
read_frame (&reader, addr, &frame) &&
|
||||||
addr < START_OF_STACK && addr >= regs->esp)
|
addr < START_OF_STACK && addr >= regs->esp)
|
||||||
{
|
{
|
||||||
trace->addresses[i++] = (void *)frame.return_address;
|
trace->addresses[i++] = (void *)frame.return_address;
|
||||||
|
|||||||
Reference in New Issue
Block a user