mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +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>
|
||||
|
||||
* 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
|
||||
KDIR := /lib/modules/$(shell uname -r)/build
|
||||
INCLUDE := -isystem $(KDIR)/include
|
||||
MODCFLAGS := -O2 -DMODULE -D__KERNEL__ -Wall ${INCLUDE}
|
||||
MODCFLAGS := -DMODULE -D__KERNEL__ -Wall ${INCLUDE}
|
||||
MODULE := sysprof-module
|
||||
|
||||
all: check $(BINARY) $(MODULE).o
|
||||
|
||||
@ -72,29 +72,50 @@ struct userspace_reader
|
||||
* Source/target buffer must be kernel space,
|
||||
* 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
|
||||
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 vm_area_struct *vma;
|
||||
struct page *page;
|
||||
void *old_buf = buf;
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
|
||||
task_lock (tsk);
|
||||
mm = tsk->mm;
|
||||
task_unlock (tsk);
|
||||
#else
|
||||
mm = get_task_mm (tsk);
|
||||
#endif
|
||||
mm = get_mm (tsk);
|
||||
|
||||
if (!mm)
|
||||
return 0;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
/* ignore errors, just check how much was sucessfully transfered */
|
||||
while (len) {
|
||||
while (len)
|
||||
{
|
||||
int bytes, ret, offset;
|
||||
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);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
|
||||
mmput(mm);
|
||||
#endif
|
||||
put_mm (mm);
|
||||
|
||||
return buf - old_buf;
|
||||
}
|
||||
@ -150,6 +169,27 @@ init_userspace_reader (userspace_reader *reader,
|
||||
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
|
||||
read_user_space (userspace_reader *reader,
|
||||
unsigned long address,
|
||||
@ -158,11 +198,10 @@ read_user_space (userspace_reader *reader,
|
||||
unsigned long cache_address = reader->cache_address;
|
||||
int index, r;
|
||||
|
||||
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 (!cache_address || cache_address != (address & PAGE_MASK))
|
||||
{
|
||||
if (!page_readable (reader, address))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
cache_address = address & PAGE_MASK;
|
||||
|
||||
@ -240,7 +279,7 @@ generate_stack_trace(struct task_struct *task,
|
||||
if (init_userspace_reader (&reader, task))
|
||||
{
|
||||
while (i < SYSPROF_MAX_ADDRESSES &&
|
||||
read_frame (&reader, addr, &frame) &&
|
||||
read_frame (&reader, addr, &frame) &&
|
||||
addr < START_OF_STACK && addr >= regs->esp)
|
||||
{
|
||||
trace->addresses[i++] = (void *)frame.return_address;
|
||||
|
||||
Reference in New Issue
Block a user