aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/sys-i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/sys-i386')
-rw-r--r--arch/um/sys-i386/ldt.c114
-rw-r--r--arch/um/sys-i386/stub_segv.c6
-rw-r--r--arch/um/sys-i386/unmap.c2
3 files changed, 66 insertions, 56 deletions
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index dc755b0b9db8..bd3c34aa52e5 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -4,96 +4,106 @@
4 */ 4 */
5 5
6#include "linux/config.h" 6#include "linux/config.h"
7#include "linux/sched.h"
7#include "linux/slab.h" 8#include "linux/slab.h"
9#include "linux/types.h"
8#include "asm/uaccess.h" 10#include "asm/uaccess.h"
9#include "asm/ptrace.h" 11#include "asm/ptrace.h"
12#include "asm/smp.h"
13#include "asm/ldt.h"
10#include "choose-mode.h" 14#include "choose-mode.h"
11#include "kern.h" 15#include "kern.h"
16#include "mode_kern.h"
12 17
13#ifdef CONFIG_MODE_TT 18#ifdef CONFIG_MODE_TT
14extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
15 19
16/* XXX this needs copy_to_user and copy_from_user */ 20extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
17 21
18int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount) 22static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
19{ 23{
20 if (!access_ok(VERIFY_READ, ptr, bytecount))
21 return -EFAULT;
22
23 return modify_ldt(func, ptr, bytecount); 24 return modify_ldt(func, ptr, bytecount);
24} 25}
26
25#endif 27#endif
26 28
27#ifdef CONFIG_MODE_SKAS 29#ifdef CONFIG_MODE_SKAS
28extern int userspace_pid[];
29 30
31#include "skas.h"
30#include "skas_ptrace.h" 32#include "skas_ptrace.h"
31 33
32int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount) 34static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
33{ 35{
34 struct ptrace_ldt ldt; 36 struct ptrace_ldt ldt;
35 void *buf; 37 u32 cpu;
36 int res, n; 38 int res;
37 39
38 buf = kmalloc(bytecount, GFP_KERNEL); 40 ldt = ((struct ptrace_ldt) { .func = func,
39 if(buf == NULL) 41 .ptr = ptr,
40 return(-ENOMEM); 42 .bytecount = bytecount });
41 43
42 res = 0; 44 cpu = get_cpu();
45 res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
46 put_cpu();
47
48 return res;
49}
50#endif
51
52int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
53{
54 struct user_desc info;
55 int res = 0;
56 void *buf = NULL;
57 void *p = NULL; /* What we pass to host. */
43 58
44 switch(func){ 59 switch(func){
45 case 1: 60 case 1:
46 case 0x11: 61 case 0x11: /* write_ldt */
47 res = copy_from_user(buf, ptr, bytecount); 62 /* Do this check now to avoid overflows. */
48 break; 63 if (bytecount != sizeof(struct user_desc)) {
49 } 64 res = -EINVAL;
65 goto out;
66 }
67
68 if(copy_from_user(&info, ptr, sizeof(info))) {
69 res = -EFAULT;
70 goto out;
71 }
50 72
51 if(res != 0){ 73 p = &info;
52 res = -EFAULT; 74 break;
75 case 0:
76 case 2: /* read_ldt */
77
78 /* The use of info avoids kmalloc on the write case, not on the
79 * read one. */
80 buf = kmalloc(bytecount, GFP_KERNEL);
81 if (!buf) {
82 res = -ENOMEM;
83 goto out;
84 }
85 p = buf;
86 default:
87 res = -ENOSYS;
53 goto out; 88 goto out;
54 } 89 }
55 90
56 ldt = ((struct ptrace_ldt) { .func = func, 91 res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
57 .ptr = buf, 92 p, bytecount);
58 .bytecount = bytecount });
59#warning Need to look up userspace_pid by cpu
60 res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
61 if(res < 0) 93 if(res < 0)
62 goto out; 94 goto out;
63 95
64 switch(func){ 96 switch(func){
65 case 0: 97 case 0:
66 case 2: 98 case 2:
67 n = res; 99 /* Modify_ldt was for reading and returned the number of read
68 res = copy_to_user(ptr, buf, n); 100 * bytes.*/
69 if(res != 0) 101 if(copy_to_user(ptr, p, res))
70 res = -EFAULT; 102 res = -EFAULT;
71 else
72 res = n;
73 break; 103 break;
74 } 104 }
75 105
76 out: 106out:
77 kfree(buf); 107 kfree(buf);
78 return(res); 108 return res;
79}
80#endif
81
82int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
83{
84 return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
85 ptr, bytecount));
86} 109}
87
88
89
90/*
91 * Overrides for Emacs so that we follow Linus's tabbing style.
92 * Emacs will notice this stuff at the end of the file and automatically
93 * adjust the settings for this buffer only. This must remain at the end
94 * of the file.
95 * ---------------------------------------------------------------------------
96 * Local variables:
97 * c-file-style: "linux"
98 * End:
99 */
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
index b251442ad0b1..68aeabe3a654 100644
--- a/arch/um/sys-i386/stub_segv.c
+++ b/arch/um/sys-i386/stub_segv.c
@@ -21,10 +21,10 @@ stub_segv_handler(int sig)
21 __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid)); 21 __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid));
22 __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;" 22 __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;"
23 "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1)); 23 "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1));
24 /* Pop the frame pointer and return address since we need to leave 24 /* Load pointer to sigcontext into esp, since we need to leave
25 * the stack in its original form when we do the sigreturn here, by 25 * the stack in its original form when we do the sigreturn here, by
26 * hand. 26 * hand.
27 */ 27 */
28 __asm__("popl %%eax ; popl %%eax ; popl %%eax ; movl %0, %%eax ; " 28 __asm__("mov %0,%%esp ; movl %1, %%eax ; "
29 "int $0x80" : : "g" (__NR_sigreturn)); 29 "int $0x80" : : "a" (sc), "g" (__NR_sigreturn));
30} 30}
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
index 136875263d27..1b0ad0e4adcd 100644
--- a/arch/um/sys-i386/unmap.c
+++ b/arch/um/sys-i386/unmap.c
@@ -15,7 +15,7 @@ int switcheroo(int fd, int prot, void *from, void *to, int size)
15 if(munmap(to, size) < 0){ 15 if(munmap(to, size) < 0){
16 return(-1); 16 return(-1);
17 } 17 }
18 if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ 18 if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
19 return(-1); 19 return(-1);
20 } 20 }
21 if(munmap(from, size) < 0){ 21 if(munmap(from, size) < 0){