aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-28 16:55:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-28 16:55:08 -0400
commit21dc2e6c6d552702736ad3603fe9b074654d3932 (patch)
tree90f3ef090166756324097493ef05417217791684 /arch/um/kernel
parentb779157dd3db6199b50e7ad64678a1ceedbeebcf (diff)
parentda028d5e5463dabb6ede2f5e3f6cced1283988cc (diff)
Merge branch 'for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML updates from Richard Weinberger: - remove hppfs ("HonePot ProcFS") - initial support for musl libc - uaccess cleanup - random cleanups and bug fixes all over the place * 'for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: (21 commits) um: Don't pollute kernel namespace with uapi um: Include sys/types.h for makedev(), major(), minor() um: Do not use stdin and stdout identifiers for struct members um: Do not use __ptr_t type for stack_t's .ss pointer um: Fix mconsole dependency um: Handle tracehook_report_syscall_entry() result um: Remove copy&paste code from init.h um: Stop abusing __KERNEL__ um: Catch unprotected user memory access um: Fix warning in setup_signal_stack_si() um: Rework uaccess code um: Add uaccess.h to ldt.c um: Add uaccess.h to syscalls_64.c um: Add asm/elf.h to vma.c um: Cleanup mem_32/64.c headers um: Remove hppfs um: Move syscall() declaration into os.h um: kernel: ksyms: Export symbol syscall() for fixing modpost issue um/os-Linux: Use char[] for syscall_stub declarations um: Use char[] for linker script address declarations ...
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/ksyms.c2
-rw-r--r--arch/um/kernel/physmem.c7
-rw-r--r--arch/um/kernel/ptrace.c7
-rw-r--r--arch/um/kernel/skas/mmu.c7
-rw-r--r--arch/um/kernel/skas/syscall.c6
-rw-r--r--arch/um/kernel/skas/uaccess.c47
-rw-r--r--arch/um/kernel/trap.c5
-rw-r--r--arch/um/kernel/um_arch.c4
8 files changed, 40 insertions, 45 deletions
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 543c04756939..232b22307fdd 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -42,3 +42,5 @@ EXPORT_SYMBOL(os_makedev);
42EXPORT_SYMBOL(add_sigio_fd); 42EXPORT_SYMBOL(add_sigio_fd);
43EXPORT_SYMBOL(ignore_sigio_fd); 43EXPORT_SYMBOL(ignore_sigio_fd);
44EXPORT_SYMBOL(sigio_broken); 44EXPORT_SYMBOL(sigio_broken);
45
46EXPORT_SYMBOL(syscall);
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 9034fc8056b4..4c9861b421fd 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -8,6 +8,7 @@
8#include <linux/mm.h> 8#include <linux/mm.h>
9#include <linux/pfn.h> 9#include <linux/pfn.h>
10#include <asm/page.h> 10#include <asm/page.h>
11#include <asm/sections.h>
11#include <as-layout.h> 12#include <as-layout.h>
12#include <init.h> 13#include <init.h>
13#include <kern.h> 14#include <kern.h>
@@ -55,8 +56,6 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
55 } 56 }
56} 57}
57 58
58extern int __syscall_stub_start;
59
60/** 59/**
61 * setup_physmem() - Setup physical memory for UML 60 * setup_physmem() - Setup physical memory for UML
62 * @start: Start address of the physical kernel memory, 61 * @start: Start address of the physical kernel memory,
@@ -110,8 +109,8 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
110 * Special kludge - This page will be mapped in to userspace processes 109 * Special kludge - This page will be mapped in to userspace processes
111 * from physmem_fd, so it needs to be written out there. 110 * from physmem_fd, so it needs to be written out there.
112 */ 111 */
113 os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); 112 os_seek_file(physmem_fd, __pa(__syscall_stub_start));
114 os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); 113 os_write_file(physmem_fd, __syscall_stub_start, PAGE_SIZE);
115 os_fsync_file(physmem_fd); 114 os_fsync_file(physmem_fd);
116 115
117 bootmap_size = init_bootmem(pfn, pfn + delta); 116 bootmap_size = init_bootmem(pfn, pfn + delta);
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 174ee5017264..6a826cbb15c4 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -8,6 +8,7 @@
8#include <linux/sched.h> 8#include <linux/sched.h>
9#include <linux/tracehook.h> 9#include <linux/tracehook.h>
10#include <asm/uaccess.h> 10#include <asm/uaccess.h>
11#include <asm/ptrace-abi.h>
11 12
12void user_enable_single_step(struct task_struct *child) 13void user_enable_single_step(struct task_struct *child)
13{ 14{
@@ -131,7 +132,7 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
131 * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and 132 * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
132 * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check 133 * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
133 */ 134 */
134void syscall_trace_enter(struct pt_regs *regs) 135int syscall_trace_enter(struct pt_regs *regs)
135{ 136{
136 audit_syscall_entry(UPT_SYSCALL_NR(&regs->regs), 137 audit_syscall_entry(UPT_SYSCALL_NR(&regs->regs),
137 UPT_SYSCALL_ARG1(&regs->regs), 138 UPT_SYSCALL_ARG1(&regs->regs),
@@ -140,9 +141,9 @@ void syscall_trace_enter(struct pt_regs *regs)
140 UPT_SYSCALL_ARG4(&regs->regs)); 141 UPT_SYSCALL_ARG4(&regs->regs));
141 142
142 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 143 if (!test_thread_flag(TIF_SYSCALL_TRACE))
143 return; 144 return 0;
144 145
145 tracehook_report_syscall_entry(regs); 146 return tracehook_report_syscall_entry(regs);
146} 147}
147 148
148void syscall_trace_leave(struct pt_regs *regs) 149void syscall_trace_leave(struct pt_regs *regs)
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 94abdcc1d6ad..fda1deba1757 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -8,12 +8,11 @@
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <asm/pgalloc.h> 9#include <asm/pgalloc.h>
10#include <asm/pgtable.h> 10#include <asm/pgtable.h>
11#include <asm/sections.h>
11#include <as-layout.h> 12#include <as-layout.h>
12#include <os.h> 13#include <os.h>
13#include <skas.h> 14#include <skas.h>
14 15
15extern int __syscall_stub_start;
16
17static int init_stub_pte(struct mm_struct *mm, unsigned long proc, 16static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
18 unsigned long kernel) 17 unsigned long kernel)
19{ 18{
@@ -93,7 +92,7 @@ void uml_setup_stubs(struct mm_struct *mm)
93 int err, ret; 92 int err, ret;
94 93
95 ret = init_stub_pte(mm, STUB_CODE, 94 ret = init_stub_pte(mm, STUB_CODE,
96 (unsigned long) &__syscall_stub_start); 95 (unsigned long) __syscall_stub_start);
97 if (ret) 96 if (ret)
98 goto out; 97 goto out;
99 98
@@ -101,7 +100,7 @@ void uml_setup_stubs(struct mm_struct *mm)
101 if (ret) 100 if (ret)
102 goto out; 101 goto out;
103 102
104 mm->context.stub_pages[0] = virt_to_page(&__syscall_stub_start); 103 mm->context.stub_pages[0] = virt_to_page(__syscall_stub_start);
105 mm->context.stub_pages[1] = virt_to_page(mm->context.id.stack); 104 mm->context.stub_pages[1] = virt_to_page(mm->context.id.stack);
106 105
107 /* dup_mmap already holds mmap_sem */ 106 /* dup_mmap already holds mmap_sem */
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index c0681e097432..d9ec0068b623 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -18,7 +18,10 @@ void handle_syscall(struct uml_pt_regs *r)
18 long result; 18 long result;
19 int syscall; 19 int syscall;
20 20
21 syscall_trace_enter(regs); 21 if (syscall_trace_enter(regs)) {
22 result = -ENOSYS;
23 goto out;
24 }
22 25
23 /* 26 /*
24 * This should go in the declaration of syscall, but when I do that, 27 * This should go in the declaration of syscall, but when I do that,
@@ -34,6 +37,7 @@ void handle_syscall(struct uml_pt_regs *r)
34 result = -ENOSYS; 37 result = -ENOSYS;
35 else result = EXECUTE_SYSCALL(syscall, regs); 38 else result = EXECUTE_SYSCALL(syscall, regs);
36 39
40out:
37 PT_REGS_SET_SYSCALL_RETURN(regs, result); 41 PT_REGS_SET_SYSCALL_RETURN(regs, result);
38 42
39 syscall_trace_leave(regs); 43 syscall_trace_leave(regs);
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 4ffb644d6c07..85ac8adb069b 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -87,10 +87,10 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
87 return n; 87 return n;
88} 88}
89 89
90static int buffer_op(unsigned long addr, int len, int is_write, 90static long buffer_op(unsigned long addr, int len, int is_write,
91 int (*op)(unsigned long, int, void *), void *arg) 91 int (*op)(unsigned long, int, void *), void *arg)
92{ 92{
93 int size, remain, n; 93 long size, remain, n;
94 94
95 size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len); 95 size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
96 remain = len; 96 remain = len;
@@ -139,18 +139,16 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg)
139 return 0; 139 return 0;
140} 140}
141 141
142int copy_from_user(void *to, const void __user *from, int n) 142long __copy_from_user(void *to, const void __user *from, unsigned long n)
143{ 143{
144 if (segment_eq(get_fs(), KERNEL_DS)) { 144 if (segment_eq(get_fs(), KERNEL_DS)) {
145 memcpy(to, (__force void*)from, n); 145 memcpy(to, (__force void*)from, n);
146 return 0; 146 return 0;
147 } 147 }
148 148
149 return access_ok(VERIFY_READ, from, n) ? 149 return buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to);
150 buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
151 n;
152} 150}
153EXPORT_SYMBOL(copy_from_user); 151EXPORT_SYMBOL(__copy_from_user);
154 152
155static int copy_chunk_to_user(unsigned long to, int len, void *arg) 153static int copy_chunk_to_user(unsigned long to, int len, void *arg)
156{ 154{
@@ -161,18 +159,16 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg)
161 return 0; 159 return 0;
162} 160}
163 161
164int copy_to_user(void __user *to, const void *from, int n) 162long __copy_to_user(void __user *to, const void *from, unsigned long n)
165{ 163{
166 if (segment_eq(get_fs(), KERNEL_DS)) { 164 if (segment_eq(get_fs(), KERNEL_DS)) {
167 memcpy((__force void *) to, from, n); 165 memcpy((__force void *) to, from, n);
168 return 0; 166 return 0;
169 } 167 }
170 168
171 return access_ok(VERIFY_WRITE, to, n) ? 169 return buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from);
172 buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
173 n;
174} 170}
175EXPORT_SYMBOL(copy_to_user); 171EXPORT_SYMBOL(__copy_to_user);
176 172
177static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) 173static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
178{ 174{
@@ -188,9 +184,9 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
188 return 0; 184 return 0;
189} 185}
190 186
191int strncpy_from_user(char *dst, const char __user *src, int count) 187long __strncpy_from_user(char *dst, const char __user *src, long count)
192{ 188{
193 int n; 189 long n;
194 char *ptr = dst; 190 char *ptr = dst;
195 191
196 if (segment_eq(get_fs(), KERNEL_DS)) { 192 if (segment_eq(get_fs(), KERNEL_DS)) {
@@ -198,16 +194,13 @@ int strncpy_from_user(char *dst, const char __user *src, int count)
198 return strnlen(dst, count); 194 return strnlen(dst, count);
199 } 195 }
200 196
201 if (!access_ok(VERIFY_READ, src, 1))
202 return -EFAULT;
203
204 n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 197 n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
205 &ptr); 198 &ptr);
206 if (n != 0) 199 if (n != 0)
207 return -EFAULT; 200 return -EFAULT;
208 return strnlen(dst, count); 201 return strnlen(dst, count);
209} 202}
210EXPORT_SYMBOL(strncpy_from_user); 203EXPORT_SYMBOL(__strncpy_from_user);
211 204
212static int clear_chunk(unsigned long addr, int len, void *unused) 205static int clear_chunk(unsigned long addr, int len, void *unused)
213{ 206{
@@ -215,22 +208,16 @@ static int clear_chunk(unsigned long addr, int len, void *unused)
215 return 0; 208 return 0;
216} 209}
217 210
218int __clear_user(void __user *mem, int len) 211unsigned long __clear_user(void __user *mem, unsigned long len)
219{
220 return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
221}
222
223int clear_user(void __user *mem, int len)
224{ 212{
225 if (segment_eq(get_fs(), KERNEL_DS)) { 213 if (segment_eq(get_fs(), KERNEL_DS)) {
226 memset((__force void*)mem, 0, len); 214 memset((__force void*)mem, 0, len);
227 return 0; 215 return 0;
228 } 216 }
229 217
230 return access_ok(VERIFY_WRITE, mem, len) ? 218 return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
231 buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len;
232} 219}
233EXPORT_SYMBOL(clear_user); 220EXPORT_SYMBOL(__clear_user);
234 221
235static int strnlen_chunk(unsigned long str, int len, void *arg) 222static int strnlen_chunk(unsigned long str, int len, void *arg)
236{ 223{
@@ -244,7 +231,7 @@ static int strnlen_chunk(unsigned long str, int len, void *arg)
244 return 0; 231 return 0;
245} 232}
246 233
247int strnlen_user(const void __user *str, int len) 234long __strnlen_user(const void __user *str, long len)
248{ 235{
249 int count = 0, n; 236 int count = 0, n;
250 237
@@ -256,4 +243,4 @@ int strnlen_user(const void __user *str, int len)
256 return count + 1; 243 return count + 1;
257 return 0; 244 return 0;
258} 245}
259EXPORT_SYMBOL(strnlen_user); 246EXPORT_SYMBOL(__strnlen_user);
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 47ff9b7f3e5d..557232f758b6 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -220,6 +220,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
220 show_regs(container_of(regs, struct pt_regs, regs)); 220 show_regs(container_of(regs, struct pt_regs, regs));
221 panic("Segfault with no mm"); 221 panic("Segfault with no mm");
222 } 222 }
223 else if (!is_user && address < TASK_SIZE) {
224 show_regs(container_of(regs, struct pt_regs, regs));
225 panic("Kernel tried to access user memory at addr 0x%lx, ip 0x%lx",
226 address, ip);
227 }
223 228
224 if (SEGV_IS_FIXABLE(&fi)) 229 if (SEGV_IS_FIXABLE(&fi))
225 err = handle_page_fault(address, ip, is_write, is_user, 230 err = handle_page_fault(address, ip, is_write, is_user,
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 07f798f4bcee..16630e75f056 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -248,8 +248,6 @@ EXPORT_SYMBOL(end_iomem);
248 248
249#define MIN_VMALLOC (32 * 1024 * 1024) 249#define MIN_VMALLOC (32 * 1024 * 1024)
250 250
251extern char __binary_start;
252
253int __init linux_main(int argc, char **argv) 251int __init linux_main(int argc, char **argv)
254{ 252{
255 unsigned long avail, diff; 253 unsigned long avail, diff;
@@ -294,7 +292,7 @@ int __init linux_main(int argc, char **argv)
294 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); 292 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
295 } 293 }
296 294
297 uml_physmem = (unsigned long) &__binary_start & PAGE_MASK; 295 uml_physmem = (unsigned long) __binary_start & PAGE_MASK;
298 296
299 /* Reserve up to 4M after the current brk */ 297 /* Reserve up to 4M after the current brk */
300 uml_reserved = ROUND_4M(brk_start) + (1 << 22); 298 uml_reserved = ROUND_4M(brk_start) + (1 << 22);