diff -Naur host/arch/i386/config.in host-ptrace/arch/i386/config.in --- host/arch/i386/config.in Fri Aug 9 15:57:14 2002 +++ host-ptrace/arch/i386/config.in Sun Nov 10 18:40:09 2002 @@ -291,6 +291,8 @@ bool ' Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF fi +bool '/proc/mm' CONFIG_PROC_MM + endmenu source drivers/mtd/Config.in diff -Naur host/arch/i386/kernel/ldt.c host-ptrace/arch/i386/kernel/ldt.c --- host/arch/i386/kernel/ldt.c Fri Oct 26 00:01:41 2001 +++ host-ptrace/arch/i386/kernel/ldt.c Sun Nov 3 18:37:48 2002 @@ -24,11 +24,12 @@ * assured by user-space anyway. Writes are atomic, to protect * the security checks done on new descriptors. */ -static int read_ldt(void * ptr, unsigned long bytecount) +static int read_ldt(struct task_struct *task, void * ptr, + unsigned long bytecount) { int err; unsigned long size; - struct mm_struct * mm = current->mm; + struct mm_struct * mm = task->mm; err = 0; if (!mm->context.segments) @@ -64,9 +65,10 @@ return err; } -static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) +static int write_ldt(struct task_struct *task, void * ptr, + unsigned long bytecount, int oldmode) { - struct mm_struct * mm = current->mm; + struct mm_struct * mm = task->mm; __u32 entry_1, entry_2, *lp; int error; struct modify_ldt_ldt_s ldt_info; @@ -148,23 +150,29 @@ return error; } -asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount) +int modify_ldt(struct task_struct *task, int func, void *ptr, + unsigned long bytecount) { int ret = -ENOSYS; switch (func) { case 0: - ret = read_ldt(ptr, bytecount); + ret = read_ldt(task, ptr, bytecount); break; case 1: - ret = write_ldt(ptr, bytecount, 1); + ret = write_ldt(task, ptr, bytecount, 1); break; case 2: ret = read_default_ldt(ptr, bytecount); break; case 0x11: - ret = write_ldt(ptr, bytecount, 0); + ret = write_ldt(task, ptr, bytecount, 0); break; } return ret; +} + +asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount) +{ + return(modify_ldt(current, func, ptr, bytecount)); } diff -Naur host/arch/i386/kernel/process.c host-ptrace/arch/i386/kernel/process.c --- host/arch/i386/kernel/process.c Fri Aug 9 15:57:14 2002 +++ host-ptrace/arch/i386/kernel/process.c Wed Nov 6 22:12:45 2002 @@ -551,13 +551,11 @@ * we do not have to muck with descriptors here, that is * done in switch_mm() as needed. */ -void copy_segments(struct task_struct *p, struct mm_struct *new_mm) +void mm_copy_segments(struct mm_struct *old_mm, struct mm_struct *new_mm) { - struct mm_struct * old_mm; void *old_ldt, *ldt; ldt = NULL; - old_mm = current->mm; if (old_mm && (old_ldt = old_mm->context.segments) != NULL) { /* * Completely new LDT, we initialize it from the parent: @@ -570,6 +568,16 @@ } new_mm->context.segments = ldt; new_mm->context.cpuvalid = ~0UL; /* valid on all CPU's - they can't have stale data */ +} + +void copy_segments(struct task_struct *p, struct mm_struct *new_mm) +{ + mm_copy_segments(current->mm, new_mm); +} + +void copy_task_segments(struct task_struct *from, struct mm_struct *new_mm) +{ + mm_copy_segments(from->mm, new_mm); } /* diff -Naur host/arch/i386/kernel/ptrace.c host-ptrace/arch/i386/kernel/ptrace.c --- host/arch/i386/kernel/ptrace.c Fri Aug 9 15:57:14 2002 +++ host-ptrace/arch/i386/kernel/ptrace.c Mon Nov 11 19:03:38 2002 @@ -147,6 +147,11 @@ put_stack_long(child, EFL_OFFSET, tmp); } +extern int modify_ldt(struct task_struct *task, int func, void *ptr, + unsigned long bytecount); + +extern struct mm_struct *proc_mm_get_mm(int fd); + asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -415,10 +420,57 @@ child->ptrace |= PT_TRACESYSGOOD; else child->ptrace &= ~PT_TRACESYSGOOD; + ret = 0; + break; + } + + case PTRACE_FAULTINFO: { + struct ptrace_faultinfo fault; + + fault = ((struct ptrace_faultinfo) + { .is_write = child->thread.error_code, + .addr = child->thread.cr2 }); + ret = copy_to_user((unsigned long *) data, &fault, + sizeof(fault)); + if(ret) + break; + break; + } + case PTRACE_SIGPENDING: + ret = copy_to_user((unsigned long *) data, + &child->pending.signal, + sizeof(child->pending.signal)); + break; + + case PTRACE_LDT: { + struct ptrace_ldt ldt; + + if(copy_from_user(&ldt, (unsigned long *) data, + sizeof(ldt))){ + ret = -EIO; + break; + } + ret = modify_ldt(child, ldt.func, ldt.ptr, ldt.bytecount); + break; + } +#ifdef CONFIG_PROC_MM + case PTRACE_SWITCH_MM: { + struct mm_struct *old = child->mm; + struct mm_struct *new = proc_mm_get_mm(data); + + if(IS_ERR(new)){ + ret = PTR_ERR(new); + break; + } + + atomic_inc(&new->mm_users); + child->mm = new; + child->active_mm = new; + mmput(old); ret = 0; break; } - +#endif default: ret = -EIO; break; diff -Naur host/arch/i386/kernel/sys_i386.c host-ptrace/arch/i386/kernel/sys_i386.c --- host/arch/i386/kernel/sys_i386.c Mon Mar 19 15:35:09 2001 +++ host-ptrace/arch/i386/kernel/sys_i386.c Mon Nov 11 17:23:25 2002 @@ -40,7 +40,7 @@ } /* common code for old and new mmaps */ -static inline long do_mmap2( +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) @@ -55,9 +55,9 @@ goto out; } - down_write(¤t->mm->mmap_sem); - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); + down_write(&mm->mmap_sem); + error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff); + up_write(&mm->mmap_sem); if (file) fput(file); @@ -69,7 +69,7 @@ unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { - return do_mmap2(addr, len, prot, flags, fd, pgoff); + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff); } /* @@ -100,7 +100,7 @@ if (a.offset & ~PAGE_MASK) goto out; - err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); + err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); out: return err; } diff -Naur host/include/asm-i386/processor.h host-ptrace/include/asm-i386/processor.h --- host/include/asm-i386/processor.h Sun Nov 10 18:47:37 2002 +++ host-ptrace/include/asm-i386/processor.h Mon Nov 11 17:33:30 2002 @@ -436,6 +436,8 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); /* Copy and release all segment info associated with a VM */ +extern void mm_copy_segments(struct mm_struct *old_mm, + struct mm_struct *new_mm); extern void copy_segments(struct task_struct *p, struct mm_struct * mm); extern void release_segments(struct mm_struct * mm); diff -Naur host/include/asm-i386/ptrace.h host-ptrace/include/asm-i386/ptrace.h --- host/include/asm-i386/ptrace.h Sun Sep 23 19:20:51 2001 +++ host-ptrace/include/asm-i386/ptrace.h Sun Nov 10 18:36:22 2002 @@ -51,6 +51,22 @@ #define PTRACE_SETOPTIONS 21 +struct ptrace_faultinfo { + int is_write; + unsigned long addr; +}; + +struct ptrace_ldt { + int func; + void *ptr; + unsigned long bytecount; +}; + +#define PTRACE_FAULTINFO 52 +#define PTRACE_SIGPENDING 53 +#define PTRACE_LDT 54 +#define PTRACE_SWITCH_MM 55 + /* options set using PTRACE_SETOPTIONS */ #define PTRACE_O_TRACESYSGOOD 0x00000001 --- linux-2.4.20/arch/um/include/skas_ptrace.h.orig Sat Mar 15 23:38:50 2003 +++ linux-2.4.20/arch/um/include/skas_ptrace.h Sun Mar 16 00:30:46 2003 @@ -6,6 +6,8 @@ #ifndef __SKAS_PTRACE_H #define __SKAS_PTRACE_H +#ifndef PTRACE_FAULTINFO + struct ptrace_faultinfo { int is_write; unsigned long addr; @@ -21,6 +23,8 @@ #define PTRACE_SIGPENDING 53 #define PTRACE_LDT 54 #define PTRACE_SWITCH_MM 55 + +#endif #endif --- linux-2.4.21/arch/ppc/kernel/syscalls.c.orig Mon Jun 30 18:15:41 2003 +++ linux-2.4.21/arch/ppc/kernel/syscalls.c Mon Jun 30 18:15:47 2003 @@ -189,7 +189,7 @@ } down_write(¤t->mm->mmap_sem); - ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff); up_write(¤t->mm->mmap_sem); if (file) fput(file); --- linux-2.4.21/arch/ia64/kernel/sys_ia64.c.orig Mon Jun 30 18:19:24 2003 +++ linux-2.4.21/arch/ia64/kernel/sys_ia64.c Mon Jun 30 18:19:48 2003 @@ -219,7 +219,7 @@ } down_write(¤t->mm->mmap_sem); - addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + addr = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff); up_write(¤t->mm->mmap_sem); out: if (file) --- linux-2.4.21/arch/sparc/kernel/sys_sparc.c~ Tue Jul 1 14:29:46 2003 +++ linux-2.4.21/arch/sparc/kernel/sys_sparc.c Tue Jul 1 20:26:26 2003 @@ -250,7 +250,7 @@ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); down_write(¤t->mm->mmap_sem); - retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + retval = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff); up_write(¤t->mm->mmap_sem); out_putf: