Commit 579a97f7ff4c0f958a5d8adcba717a205bb58567

Authored by bellard
1 parent 44f8625d

Linux user memory access API change (initial patch by Thayne Harbaugh)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3583 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -260,7 +260,7 @@ endif @@ -260,7 +260,7 @@ endif
260 260
261 ifdef CONFIG_LINUX_USER 261 ifdef CONFIG_LINUX_USER
262 OBJS= main.o syscall.o strace.o mmap.o signal.o path.o osdep.o thunk.o \ 262 OBJS= main.o syscall.o strace.o mmap.o signal.o path.o osdep.o thunk.o \
263 - elfload.o linuxload.o 263 + elfload.o linuxload.o uaccess.o
264 LIBS+= $(AIOLIBS) 264 LIBS+= $(AIOLIBS)
265 ifdef TARGET_HAS_BFLT 265 ifdef TARGET_HAS_BFLT
266 OBJS+= flatload.o 266 OBJS+= flatload.o
arm-semi.c
@@ -184,9 +184,11 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -184,9 +184,11 @@ uint32_t do_arm_semihosting(CPUState *env)
184 args = env->regs[1]; 184 args = env->regs[1];
185 switch (nr) { 185 switch (nr) {
186 case SYS_OPEN: 186 case SYS_OPEN:
187 - s = lock_user_string(ARG(0)); 187 + if (!(s = lock_user_string(ARG(0))))
  188 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  189 + return (uint32_t)-1;
188 if (ARG(1) >= 12) 190 if (ARG(1) >= 12)
189 - return (uint32_t)-1; 191 + return (uint32_t)-1;
190 if (strcmp(s, ":tt") == 0) { 192 if (strcmp(s, ":tt") == 0) {
191 if (ARG(1) < 4) 193 if (ARG(1) < 4)
192 return STDIN_FILENO; 194 return STDIN_FILENO;
@@ -221,7 +223,9 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -221,7 +223,9 @@ uint32_t do_arm_semihosting(CPUState *env)
221 } 223 }
222 } 224 }
223 case SYS_WRITE0: 225 case SYS_WRITE0:
224 - s = lock_user_string(args); 226 + if (!(s = lock_user_string(args)))
  227 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  228 + return (uint32_t)-1;
225 len = strlen(s); 229 len = strlen(s);
226 if (use_gdb_syscalls()) { 230 if (use_gdb_syscalls()) {
227 gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len); 231 gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len);
@@ -238,7 +242,9 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -238,7 +242,9 @@ uint32_t do_arm_semihosting(CPUState *env)
238 gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len); 242 gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len);
239 return env->regs[0]; 243 return env->regs[0];
240 } else { 244 } else {
241 - s = lock_user(ARG(1), len, 1); 245 + if (!(s = lock_user(VERIFY_READ, ARG(1), len, 1)))
  246 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  247 + return (uint32_t)-1;
242 ret = set_swi_errno(ts, write(ARG(0), s, len)); 248 ret = set_swi_errno(ts, write(ARG(0), s, len));
243 unlock_user(s, ARG(1), 0); 249 unlock_user(s, ARG(1), 0);
244 if (ret == (uint32_t)-1) 250 if (ret == (uint32_t)-1)
@@ -252,7 +258,9 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -252,7 +258,9 @@ uint32_t do_arm_semihosting(CPUState *env)
252 gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len); 258 gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len);
253 return env->regs[0]; 259 return env->regs[0];
254 } else { 260 } else {
255 - s = lock_user(ARG(1), len, 0); 261 + if (!(s = lock_user(VERIFY_WRITE, ARG(1), len, 0)))
  262 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  263 + return (uint32_t)-1;
256 do 264 do
257 ret = set_swi_errno(ts, read(ARG(0), s, len)); 265 ret = set_swi_errno(ts, read(ARG(0), s, len));
258 while (ret == -1 && errno == EINTR); 266 while (ret == -1 && errno == EINTR);
@@ -301,7 +309,9 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -301,7 +309,9 @@ uint32_t do_arm_semihosting(CPUState *env)
301 gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1); 309 gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1);
302 ret = env->regs[0]; 310 ret = env->regs[0];
303 } else { 311 } else {
304 - s = lock_user_string(ARG(0)); 312 + if (!(s = lock_user_string(ARG(0))))
  313 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  314 + return (uint32_t)-1;
305 ret = set_swi_errno(ts, remove(s)); 315 ret = set_swi_errno(ts, remove(s));
306 unlock_user(s, ARG(0), 0); 316 unlock_user(s, ARG(0), 0);
307 } 317 }
@@ -315,9 +325,15 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -315,9 +325,15 @@ uint32_t do_arm_semihosting(CPUState *env)
315 char *s2; 325 char *s2;
316 s = lock_user_string(ARG(0)); 326 s = lock_user_string(ARG(0));
317 s2 = lock_user_string(ARG(2)); 327 s2 = lock_user_string(ARG(2));
318 - ret = set_swi_errno(ts, rename(s, s2));  
319 - unlock_user(s2, ARG(2), 0);  
320 - unlock_user(s, ARG(0), 0); 328 + if (!s || !s2)
  329 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  330 + ret = (uint32_t)-1;
  331 + else
  332 + ret = set_swi_errno(ts, rename(s, s2));
  333 + if (s2)
  334 + unlock_user(s2, ARG(2), 0);
  335 + if (s)
  336 + unlock_user(s, ARG(0), 0);
321 return ret; 337 return ret;
322 } 338 }
323 case SYS_CLOCK: 339 case SYS_CLOCK:
@@ -329,7 +345,9 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -329,7 +345,9 @@ uint32_t do_arm_semihosting(CPUState *env)
329 gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1); 345 gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1);
330 return env->regs[0]; 346 return env->regs[0];
331 } else { 347 } else {
332 - s = lock_user_string(ARG(0)); 348 + if (!(s = lock_user_string(ARG(0))))
  349 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  350 + return (uint32_t)-1;
333 ret = set_swi_errno(ts, system(s)); 351 ret = set_swi_errno(ts, system(s));
334 unlock_user(s, ARG(0), 0); 352 unlock_user(s, ARG(0), 0);
335 } 353 }
@@ -346,7 +364,11 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -346,7 +364,11 @@ uint32_t do_arm_semihosting(CPUState *env)
346 char **arg = ts->info->host_argv; 364 char **arg = ts->info->host_argv;
347 int len = ARG(1); 365 int len = ARG(1);
348 /* lock the buffer on the ARM side */ 366 /* lock the buffer on the ARM side */
349 - char *cmdline_buffer = (char*)lock_user(ARG(0), len, 0); 367 + char *cmdline_buffer = (char*)lock_user(VERIFY_WRITE, ARG(0), len, 0);
  368 +
  369 + if (!cmdline_buffer)
  370 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  371 + return (uint32_t)-1;
350 372
351 s = cmdline_buffer; 373 s = cmdline_buffer;
352 while (*arg && len > 2) { 374 while (*arg && len > 2) {
@@ -402,7 +424,9 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -402,7 +424,9 @@ uint32_t do_arm_semihosting(CPUState *env)
402 ts->heap_limit = limit; 424 ts->heap_limit = limit;
403 } 425 }
404 426
405 - ptr = lock_user(ARG(0), 16, 0); 427 + if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0)))
  428 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  429 + return (uint32_t)-1;
406 ptr[0] = tswap32(ts->heap_base); 430 ptr[0] = tswap32(ts->heap_base);
407 ptr[1] = tswap32(ts->heap_limit); 431 ptr[1] = tswap32(ts->heap_limit);
408 ptr[2] = tswap32(ts->stack_base); 432 ptr[2] = tswap32(ts->stack_base);
@@ -410,7 +434,9 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -410,7 +434,9 @@ uint32_t do_arm_semihosting(CPUState *env)
410 unlock_user(ptr, ARG(0), 16); 434 unlock_user(ptr, ARG(0), 16);
411 #else 435 #else
412 limit = ram_size; 436 limit = ram_size;
413 - ptr = lock_user(ARG(0), 16, 0); 437 + if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0)))
  438 + /* FIXME - should this error code be -TARGET_EFAULT ? */
  439 + return (uint32_t)-1;
414 /* TODO: Make this use the limit of the loaded application. */ 440 /* TODO: Make this use the limit of the loaded application. */
415 ptr[0] = tswap32(limit / 2); 441 ptr[0] = tswap32(limit / 2);
416 ptr[1] = tswap32(limit); 442 ptr[1] = tswap32(limit);
@@ -2510,13 +2510,19 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, @@ -2510,13 +2510,19 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
2510 if (is_write) { 2510 if (is_write) {
2511 if (!(flags & PAGE_WRITE)) 2511 if (!(flags & PAGE_WRITE))
2512 return; 2512 return;
2513 - p = lock_user(addr, len, 0); 2513 + /* XXX: this code should not depend on lock_user */
  2514 + if (!(p = lock_user(VERIFY_WRITE, addr, len, 0)))
  2515 + /* FIXME - should this return an error rather than just fail? */
  2516 + return;
2514 memcpy(p, buf, len); 2517 memcpy(p, buf, len);
2515 unlock_user(p, addr, len); 2518 unlock_user(p, addr, len);
2516 } else { 2519 } else {
2517 if (!(flags & PAGE_READ)) 2520 if (!(flags & PAGE_READ))
2518 return; 2521 return;
2519 - p = lock_user(addr, len, 1); 2522 + /* XXX: this code should not depend on lock_user */
  2523 + if (!(p = lock_user(VERIFY_READ, addr, len, 1)))
  2524 + /* FIXME - should this return an error rather than just fail? */
  2525 + return;
2520 memcpy(buf, p, len); 2526 memcpy(buf, p, len);
2521 unlock_user(p, addr, 0); 2527 unlock_user(p, addr, 0);
2522 } 2528 }
linux-user/elfload.c
@@ -677,7 +677,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, @@ -677,7 +677,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
677 for (i = 0 ; i < MAX_ARG_PAGES ; i++) { 677 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
678 if (bprm->page[i]) { 678 if (bprm->page[i]) {
679 info->rss++; 679 info->rss++;
680 - 680 + /* FIXME - check return value of memcpy_to_target() for failure */
681 memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE); 681 memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
682 free(bprm->page[i]); 682 free(bprm->page[i]);
683 } 683 }
@@ -760,6 +760,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, @@ -760,6 +760,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
760 size_t len = strlen(k_platform) + 1; 760 size_t len = strlen(k_platform) + 1;
761 sp -= (len + n - 1) & ~(n - 1); 761 sp -= (len + n - 1) & ~(n - 1);
762 u_platform = sp; 762 u_platform = sp;
  763 + /* FIXME - check return value of memcpy_to_target() for failure */
763 memcpy_to_target(sp, k_platform, len); 764 memcpy_to_target(sp, k_platform, len);
764 } 765 }
765 /* 766 /*
linux-user/flatload.c
@@ -108,7 +108,7 @@ int target_pread(int fd, abi_ulong ptr, abi_ulong len, @@ -108,7 +108,7 @@ int target_pread(int fd, abi_ulong ptr, abi_ulong len,
108 void *buf; 108 void *buf;
109 int ret; 109 int ret;
110 110
111 - buf = lock_user(ptr, len, 0); 111 + buf = lock_user(VERIFY_WRITE, ptr, len, 0);
112 ret = pread(fd, buf, len, offset); 112 ret = pread(fd, buf, len, offset);
113 unlock_user(buf, ptr, len); 113 unlock_user(buf, ptr, len);
114 return ret; 114 return ret;
linux-user/linuxload.c
@@ -13,14 +13,17 @@ @@ -13,14 +13,17 @@
13 #define NGROUPS 32 13 #define NGROUPS 32
14 14
15 /* ??? This should really be somewhere else. */ 15 /* ??? This should really be somewhere else. */
16 -void memcpy_to_target(abi_ulong dest, const void *src,  
17 - unsigned long len) 16 +abi_long memcpy_to_target(abi_ulong dest, const void *src,
  17 + unsigned long len)
18 { 18 {
19 void *host_ptr; 19 void *host_ptr;
20 20
21 - host_ptr = lock_user(dest, len, 0); 21 + host_ptr = lock_user(VERIFY_WRITE, dest, len, 0);
  22 + if (!host_ptr)
  23 + return -TARGET_EFAULT;
22 memcpy(host_ptr, src, len); 24 memcpy(host_ptr, src, len);
23 unlock_user(host_ptr, dest, 1); 25 unlock_user(host_ptr, dest, 1);
  26 + return 0;
24 } 27 }
25 28
26 static int in_group_p(gid_t g) 29 static int in_group_p(gid_t g)
linux-user/qemu.h
@@ -146,8 +146,8 @@ int load_elf_binary_multi(struct linux_binprm *bprm, @@ -146,8 +146,8 @@ int load_elf_binary_multi(struct linux_binprm *bprm,
146 struct image_info *info); 146 struct image_info *info);
147 #endif 147 #endif
148 148
149 -void memcpy_to_target(abi_ulong dest, const void *src,  
150 - unsigned long len); 149 +abi_long memcpy_to_target(abi_ulong dest, const void *src,
  150 + unsigned long len);
151 void target_set_brk(abi_ulong new_brk); 151 void target_set_brk(abi_ulong new_brk);
152 abi_long do_brk(abi_ulong new_brk); 152 abi_long do_brk(abi_ulong new_brk);
153 void syscall_init(void); 153 void syscall_init(void);
@@ -179,9 +179,7 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); @@ -179,9 +179,7 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
179 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); 179 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
180 long do_sigreturn(CPUState *env); 180 long do_sigreturn(CPUState *env);
181 long do_rt_sigreturn(CPUState *env); 181 long do_rt_sigreturn(CPUState *env);
182 -int do_sigaltstack(const struct target_sigaltstack *uss,  
183 - struct target_sigaltstack *uoss,  
184 - abi_ulong sp); 182 +abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
185 183
186 #ifdef TARGET_I386 184 #ifdef TARGET_I386
187 /* vm86.c */ 185 /* vm86.c */
@@ -207,12 +205,15 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); @@ -207,12 +205,15 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
207 /* user access */ 205 /* user access */
208 206
209 #define VERIFY_READ 0 207 #define VERIFY_READ 0
210 -#define VERIFY_WRITE 1 208 +#define VERIFY_WRITE 1 /* implies read access */
211 209
212 #define access_ok(type,addr,size) \ 210 #define access_ok(type,addr,size) \
213 (page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0) 211 (page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0)
214 212
215 /* NOTE __get_user and __put_user use host pointers and don't check access. */ 213 /* NOTE __get_user and __put_user use host pointers and don't check access. */
  214 +/* These are usually used to access struct data members once the
  215 + * struct has been locked - usually with lock_user_struct().
  216 + */
216 #define __put_user(x, hptr)\ 217 #define __put_user(x, hptr)\
217 ({\ 218 ({\
218 int size = sizeof(*hptr);\ 219 int size = sizeof(*hptr);\
@@ -257,26 +258,44 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); @@ -257,26 +258,44 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
257 0;\ 258 0;\
258 }) 259 })
259 260
260 -#define put_user(x,ptr)\  
261 -({\  
262 - int __ret;\  
263 - if (access_ok(VERIFY_WRITE, ptr, sizeof(*ptr)))\  
264 - __ret = __put_user(x, ptr);\  
265 - else\  
266 - __ret = -EFAULT;\  
267 - __ret;\ 261 +/* put_user()/get_user() take a guest address and check access */
  262 +/* These are usually used to access an atomic data type, such as an int,
  263 + * that has been passed by address. These internally perform locking
  264 + * and unlocking on the data type.
  265 + */
  266 +#define put_user(x, gaddr, target_type) \
  267 +({ \
  268 + abi_ulong __gaddr = (gaddr); \
  269 + target_type *__hptr; \
  270 + abi_long __ret; \
  271 + if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
  272 + __ret = __put_user((x), __hptr); \
  273 + unlock_user(__hptr, __gaddr, sizeof(target_type)); \
  274 + } else \
  275 + __ret = -TARGET_EFAULT; \
  276 + __ret; \
268 }) 277 })
269 278
270 -#define get_user(x,ptr)\  
271 -({\  
272 - int __ret;\  
273 - if (access_ok(VERIFY_READ, ptr, sizeof(*ptr)))\  
274 - __ret = __get_user(x, ptr);\  
275 - else\  
276 - __ret = -EFAULT;\  
277 - __ret;\ 279 +#define get_user(x, gaddr, target_type) \
  280 +({ \
  281 + abi_ulong __gaddr = (gaddr); \
  282 + target_type *__hptr; \
  283 + abi_long __ret; \
  284 + if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
  285 + __ret = __get_user((x), __hptr); \
  286 + unlock_user(__hptr, __gaddr, 0); \
  287 + } else \
  288 + __ret = -TARGET_EFAULT; \
  289 + __ret; \
278 }) 290 })
279 291
  292 +/* copy_from_user() and copy_to_user() are usually used to copy data
  293 + * buffers between the target and host. These internally perform
  294 + * locking/unlocking of the memory.
  295 + */
  296 +abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
  297 +abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
  298 +
280 /* Functions for accessing guest memory. The tget and tput functions 299 /* Functions for accessing guest memory. The tget and tput functions
281 read/write single values, byteswapping as neccessary. The lock_user 300 read/write single values, byteswapping as neccessary. The lock_user
282 gets a pointer to a contiguous area of guest memory, but does not perform 301 gets a pointer to a contiguous area of guest memory, but does not perform
@@ -285,53 +304,61 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); @@ -285,53 +304,61 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
285 304
286 /* Lock an area of guest memory into the host. If copy is true then the 305 /* Lock an area of guest memory into the host. If copy is true then the
287 host area will have the same contents as the guest. */ 306 host area will have the same contents as the guest. */
288 -static inline void *lock_user(abi_ulong guest_addr, long len, int copy) 307 +static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
289 { 308 {
  309 + if (!access_ok(type, guest_addr, len))
  310 + return NULL;
290 #ifdef DEBUG_REMAP 311 #ifdef DEBUG_REMAP
291 - void *addr;  
292 - addr = malloc(len);  
293 - if (copy)  
294 - memcpy(addr, g2h(guest_addr), len);  
295 - else  
296 - memset(addr, 0, len);  
297 - return addr; 312 + {
  313 + void *addr;
  314 + addr = malloc(len);
  315 + if (copy)
  316 + memcpy(addr, g2h(guest_addr), len);
  317 + else
  318 + memset(addr, 0, len);
  319 + return addr;
  320 + }
298 #else 321 #else
299 return g2h(guest_addr); 322 return g2h(guest_addr);
300 #endif 323 #endif
301 } 324 }
302 325
303 -/* Unlock an area of guest memory. The first LEN bytes must be flushed back  
304 - to guest memory. */  
305 -static inline void unlock_user(void *host_addr, abi_ulong guest_addr, 326 +/* Unlock an area of guest memory. The first LEN bytes must be
  327 + flushed back to guest memory. host_ptr = NULL is explicitely
  328 + allowed and does nothing. */
  329 +static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
306 long len) 330 long len)
307 { 331 {
  332 +
308 #ifdef DEBUG_REMAP 333 #ifdef DEBUG_REMAP
309 - if (host_addr == g2h(guest_addr)) 334 + if (!host_ptr)
  335 + return;
  336 + if (host_ptr == g2h(guest_addr))
310 return; 337 return;
311 if (len > 0) 338 if (len > 0)
312 - memcpy(g2h(guest_addr), host_addr, len);  
313 - free(host_addr); 339 + memcpy(g2h(guest_ptr), host_ptr, len);
  340 + free(host_ptr);
314 #endif 341 #endif
315 } 342 }
316 343
317 -/* Return the length of a string in target memory. */  
318 -static inline int target_strlen(abi_ulong ptr)  
319 -{  
320 - return strlen(g2h(ptr));  
321 -} 344 +/* Return the length of a string in target memory or -TARGET_EFAULT if
  345 + access error. */
  346 +abi_long target_strlen(abi_ulong gaddr);
322 347
323 /* Like lock_user but for null terminated strings. */ 348 /* Like lock_user but for null terminated strings. */
324 static inline void *lock_user_string(abi_ulong guest_addr) 349 static inline void *lock_user_string(abi_ulong guest_addr)
325 { 350 {
326 - long len;  
327 - len = target_strlen(guest_addr) + 1;  
328 - return lock_user(guest_addr, len, 1); 351 + abi_long len;
  352 + len = target_strlen(guest_addr);
  353 + if (len < 0)
  354 + return NULL;
  355 + return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
329 } 356 }
330 357
331 /* Helper macros for locking/ulocking a target struct. */ 358 /* Helper macros for locking/ulocking a target struct. */
332 -#define lock_user_struct(host_ptr, guest_addr, copy) \  
333 - host_ptr = lock_user(guest_addr, sizeof(*host_ptr), copy)  
334 -#define unlock_user_struct(host_ptr, guest_addr, copy) \ 359 +#define lock_user_struct(type, host_ptr, guest_addr, copy) \
  360 + (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
  361 +#define unlock_user_struct(host_ptr, guest_addr, copy) \
335 unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0) 362 unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
336 363
337 #define tget8(addr) ldub(addr) 364 #define tget8(addr) ldub(addr)
linux-user/signal.c
@@ -435,31 +435,32 @@ static void host_signal_handler(int host_signum, siginfo_t *info, @@ -435,31 +435,32 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
435 } 435 }
436 436
437 /* do_sigaltstack() returns target values and errnos. */ 437 /* do_sigaltstack() returns target values and errnos. */
438 -int do_sigaltstack(const struct target_sigaltstack *uss,  
439 - struct target_sigaltstack *uoss,  
440 - abi_ulong sp) 438 +/* compare linux/kernel/signal.c:do_sigaltstack() */
  439 +abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
441 { 440 {
442 int ret; 441 int ret;
443 struct target_sigaltstack oss; 442 struct target_sigaltstack oss;
444 443
445 /* XXX: test errors */ 444 /* XXX: test errors */
446 - if(uoss) 445 + if(uoss_addr)
447 { 446 {
448 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp); 447 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
449 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size); 448 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
450 __put_user(sas_ss_flags(sp), &oss.ss_flags); 449 __put_user(sas_ss_flags(sp), &oss.ss_flags);
451 } 450 }
452 451
453 - if(uss) 452 + if(uss_addr)
454 { 453 {
455 - struct target_sigaltstack ss; 454 + struct target_sigaltstack *uss;
  455 + struct target_sigaltstack ss;
456 456
457 ret = -TARGET_EFAULT; 457 ret = -TARGET_EFAULT;
458 - if (!access_ok(VERIFY_READ, uss, sizeof(*uss)) 458 + if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
459 || __get_user(ss.ss_sp, &uss->ss_sp) 459 || __get_user(ss.ss_sp, &uss->ss_sp)
460 || __get_user(ss.ss_size, &uss->ss_size) 460 || __get_user(ss.ss_size, &uss->ss_size)
461 || __get_user(ss.ss_flags, &uss->ss_flags)) 461 || __get_user(ss.ss_flags, &uss->ss_flags))
462 goto out; 462 goto out;
  463 + unlock_user_struct(uss, uss_addr, 0);
463 464
464 ret = -TARGET_EPERM; 465 ret = -TARGET_EPERM;
465 if (on_sig_stack(sp)) 466 if (on_sig_stack(sp))
@@ -484,11 +485,10 @@ int do_sigaltstack(const struct target_sigaltstack *uss, @@ -484,11 +485,10 @@ int do_sigaltstack(const struct target_sigaltstack *uss,
484 target_sigaltstack_used.ss_size = ss.ss_size; 485 target_sigaltstack_used.ss_size = ss.ss_size;
485 } 486 }
486 487
487 - if (uoss) { 488 + if (uoss_addr) {
488 ret = -TARGET_EFAULT; 489 ret = -TARGET_EFAULT;
489 - if (!access_ok(VERIFY_WRITE, uoss, sizeof(oss))) 490 + if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
490 goto out; 491 goto out;
491 - memcpy(uoss, &oss, sizeof(oss));  
492 } 492 }
493 493
494 ret = 0; 494 ret = 0;
@@ -671,6 +671,7 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate, @@ -671,6 +671,7 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
671 { 671 {
672 int err = 0; 672 int err = 0;
673 673
  674 + /* already locked in setup_frame() */
674 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs); 675 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
675 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs); 676 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
676 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es); 677 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
@@ -706,7 +707,7 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate, @@ -706,7 +707,7 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
706 * Determine which stack to use.. 707 * Determine which stack to use..
707 */ 708 */
708 709
709 -static inline void * 710 +static inline abi_ulong
710 get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) 711 get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
711 { 712 {
712 unsigned long esp; 713 unsigned long esp;
@@ -726,19 +727,22 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) @@ -726,19 +727,22 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
726 ka->sa.sa_restorer) { 727 ka->sa.sa_restorer) {
727 esp = (unsigned long) ka->sa.sa_restorer; 728 esp = (unsigned long) ka->sa.sa_restorer;
728 } 729 }
729 - return g2h((esp - frame_size) & -8ul); 730 + return (esp - frame_size) & -8ul;
730 } 731 }
731 732
  733 +/* compare linux/arch/i386/kernel/signal.c:setup_frame() */
732 static void setup_frame(int sig, struct emulated_sigaction *ka, 734 static void setup_frame(int sig, struct emulated_sigaction *ka,
733 target_sigset_t *set, CPUX86State *env) 735 target_sigset_t *set, CPUX86State *env)
734 { 736 {
  737 + abi_ulong frame_addr;
735 struct sigframe *frame; 738 struct sigframe *frame;
736 int i, err = 0; 739 int i, err = 0;
737 740
738 - frame = get_sigframe(ka, env, sizeof(*frame)); 741 + frame_addr = get_sigframe(ka, env, sizeof(*frame));
739 742
740 - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 743 + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
741 goto give_sigsegv; 744 goto give_sigsegv;
  745 +
742 err |= __put_user((/*current->exec_domain 746 err |= __put_user((/*current->exec_domain
743 && current->exec_domain->signal_invmap 747 && current->exec_domain->signal_invmap
744 && sig < 32 748 && sig < 32
@@ -786,24 +790,29 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -786,24 +790,29 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
786 cpu_x86_load_seg(env, R_CS, __USER_CS); 790 cpu_x86_load_seg(env, R_CS, __USER_CS);
787 env->eflags &= ~TF_MASK; 791 env->eflags &= ~TF_MASK;
788 792
  793 + unlock_user_struct(frame, frame_addr, 1);
  794 +
789 return; 795 return;
790 796
791 give_sigsegv: 797 give_sigsegv:
  798 + unlock_user_struct(frame, frame_addr, 1);
792 if (sig == TARGET_SIGSEGV) 799 if (sig == TARGET_SIGSEGV)
793 ka->sa._sa_handler = TARGET_SIG_DFL; 800 ka->sa._sa_handler = TARGET_SIG_DFL;
794 force_sig(TARGET_SIGSEGV /* , current */); 801 force_sig(TARGET_SIGSEGV /* , current */);
795 } 802 }
796 803
  804 +/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
797 static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 805 static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
798 target_siginfo_t *info, 806 target_siginfo_t *info,
799 target_sigset_t *set, CPUX86State *env) 807 target_sigset_t *set, CPUX86State *env)
800 { 808 {
  809 + abi_ulong frame_addr;
801 struct rt_sigframe *frame; 810 struct rt_sigframe *frame;
802 int i, err = 0; 811 int i, err = 0;
803 812
804 - frame = get_sigframe(ka, env, sizeof(*frame)); 813 + frame_addr = get_sigframe(ka, env, sizeof(*frame));
805 814
806 - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 815 + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
807 goto give_sigsegv; 816 goto give_sigsegv;
808 817
809 err |= __put_user((/*current->exec_domain 818 err |= __put_user((/*current->exec_domain
@@ -859,9 +868,12 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -859,9 +868,12 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
859 cpu_x86_load_seg(env, R_CS, __USER_CS); 868 cpu_x86_load_seg(env, R_CS, __USER_CS);
860 env->eflags &= ~TF_MASK; 869 env->eflags &= ~TF_MASK;
861 870
  871 + unlock_user_struct(frame, frame_addr, 1);
  872 +
862 return; 873 return;
863 874
864 give_sigsegv: 875 give_sigsegv:
  876 + unlock_user_struct(frame, frame_addr, 1);
865 if (sig == TARGET_SIGSEGV) 877 if (sig == TARGET_SIGSEGV)
866 ka->sa._sa_handler = TARGET_SIG_DFL; 878 ka->sa._sa_handler = TARGET_SIG_DFL;
867 force_sig(TARGET_SIGSEGV /* , current */); 879 force_sig(TARGET_SIGSEGV /* , current */);
@@ -918,7 +930,8 @@ badframe: @@ -918,7 +930,8 @@ badframe:
918 930
919 long do_sigreturn(CPUX86State *env) 931 long do_sigreturn(CPUX86State *env)
920 { 932 {
921 - struct sigframe *frame = (struct sigframe *)g2h(env->regs[R_ESP] - 8); 933 + struct sigframe *frame;
  934 + abi_ulong frame_addr = env->regs[R_ESP] - 8;
922 target_sigset_t target_set; 935 target_sigset_t target_set;
923 sigset_t set; 936 sigset_t set;
924 int eax, i; 937 int eax, i;
@@ -926,6 +939,8 @@ long do_sigreturn(CPUX86State *env) @@ -926,6 +939,8 @@ long do_sigreturn(CPUX86State *env)
926 #if defined(DEBUG_SIGNAL) 939 #if defined(DEBUG_SIGNAL)
927 fprintf(stderr, "do_sigreturn\n"); 940 fprintf(stderr, "do_sigreturn\n");
928 #endif 941 #endif
  942 + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
  943 + goto badframe;
929 /* set blocked signals */ 944 /* set blocked signals */
930 if (__get_user(target_set.sig[0], &frame->sc.oldmask)) 945 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
931 goto badframe; 946 goto badframe;
@@ -940,9 +955,11 @@ long do_sigreturn(CPUX86State *env) @@ -940,9 +955,11 @@ long do_sigreturn(CPUX86State *env)
940 /* restore registers */ 955 /* restore registers */
941 if (restore_sigcontext(env, &frame->sc, &eax)) 956 if (restore_sigcontext(env, &frame->sc, &eax))
942 goto badframe; 957 goto badframe;
  958 + unlock_user_struct(frame, frame_addr, 0);
943 return eax; 959 return eax;
944 960
945 badframe: 961 badframe:
  962 + unlock_user_struct(frame, frame_addr, 0);
946 force_sig(TARGET_SIGSEGV); 963 force_sig(TARGET_SIGSEGV);
947 return 0; 964 return 0;
948 } 965 }
@@ -963,7 +980,7 @@ long do_rt_sigreturn(CPUX86State *env) @@ -963,7 +980,7 @@ long do_rt_sigreturn(CPUX86State *env)
963 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax)) 980 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
964 goto badframe; 981 goto badframe;
965 982
966 - if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT) 983 + if (do_sigaltstack(h2g(&frame->uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
967 goto badframe; 984 goto badframe;
968 985
969 return eax; 986 return eax;
@@ -1086,7 +1103,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ @@ -1086,7 +1103,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1086 return err; 1103 return err;
1087 } 1104 }
1088 1105
1089 -static inline void * 1106 +static inline abi_ulong
1090 get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) 1107 get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
1091 { 1108 {
1092 unsigned long sp = regs->regs[13]; 1109 unsigned long sp = regs->regs[13];
@@ -1099,7 +1116,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) @@ -1099,7 +1116,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
1099 /* 1116 /*
1100 * ATPCS B01 mandates 8-byte alignment 1117 * ATPCS B01 mandates 8-byte alignment
1101 */ 1118 */
1102 - return g2h((sp - framesize) & ~7); 1119 + return (sp - framesize) & ~7;
1103 } 1120 }
1104 1121
1105 static int 1122 static int
@@ -1167,33 +1184,43 @@ setup_return(CPUState *env, struct emulated_sigaction *ka, @@ -1167,33 +1184,43 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
1167 return 0; 1184 return 0;
1168 } 1185 }
1169 1186
  1187 +/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1170 static void setup_frame(int usig, struct emulated_sigaction *ka, 1188 static void setup_frame(int usig, struct emulated_sigaction *ka,
1171 target_sigset_t *set, CPUState *regs) 1189 target_sigset_t *set, CPUState *regs)
1172 { 1190 {
1173 - struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame)); 1191 + struct sigframe *frame;
  1192 + abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1174 int i, err = 0; 1193 int i, err = 0;
1175 1194
  1195 + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
  1196 + return;
  1197 +
1176 err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]); 1198 err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
1177 1199
1178 for(i = 1; i < TARGET_NSIG_WORDS; i++) { 1200 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1179 if (__put_user(set->sig[i], &frame->extramask[i - 1])) 1201 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1180 - return; 1202 + goto end;
1181 } 1203 }
1182 1204
1183 if (err == 0) 1205 if (err == 0)
1184 err = setup_return(regs, ka, &frame->retcode, frame, usig); 1206 err = setup_return(regs, ka, &frame->retcode, frame, usig);
  1207 +
  1208 +end:
  1209 + unlock_user_struct(frame, frame_addr, 1);
1185 // return err; 1210 // return err;
1186 } 1211 }
1187 1212
  1213 +/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1188 static void setup_rt_frame(int usig, struct emulated_sigaction *ka, 1214 static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1189 target_siginfo_t *info, 1215 target_siginfo_t *info,
1190 target_sigset_t *set, CPUState *env) 1216 target_sigset_t *set, CPUState *env)
1191 { 1217 {
1192 - struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame)); 1218 + struct rt_sigframe *frame;
  1219 + abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1193 struct target_sigaltstack stack; 1220 struct target_sigaltstack stack;
1194 int i, err = 0; 1221 int i, err = 0;
1195 1222
1196 - if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 1223 + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1197 return /* 1 */; 1224 return /* 1 */;
1198 1225
1199 __put_user_error(&frame->info, (abi_ulong *)&frame->pinfo, err); 1226 __put_user_error(&frame->info, (abi_ulong *)&frame->pinfo, err);
@@ -1207,16 +1234,13 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka, @@ -1207,16 +1234,13 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1207 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp); 1234 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1208 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size); 1235 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1209 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags); 1236 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1210 - if (!access_ok(VERIFY_WRITE, &frame->uc.tuc_stack, sizeof(stack)))  
1211 - err = 1;  
1212 - else  
1213 - memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack)); 1237 + err |= copy_to_user(&frame->uc.tuc_stack, &stack, sizeof(stack));
1214 1238
1215 err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/ 1239 err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
1216 env, set->sig[0]); 1240 env, set->sig[0]);
1217 for(i = 0; i < TARGET_NSIG_WORDS; i++) { 1241 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1218 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i])) 1242 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1219 - return; 1243 + goto end;
1220 } 1244 }
1221 1245
1222 if (err == 0) 1246 if (err == 0)
@@ -1232,6 +1256,9 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka, @@ -1232,6 +1256,9 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1232 env->regs[2] = (abi_ulong)frame->puc; 1256 env->regs[2] = (abi_ulong)frame->puc;
1233 } 1257 }
1234 1258
  1259 +end:
  1260 + unlock_user_struct(frame, frame_addr, 1);
  1261 +
1235 // return err; 1262 // return err;
1236 } 1263 }
1237 1264
@@ -1338,7 +1365,7 @@ long do_rt_sigreturn(CPUState *env) @@ -1338,7 +1365,7 @@ long do_rt_sigreturn(CPUState *env)
1338 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) 1365 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1339 goto badframe; 1366 goto badframe;
1340 1367
1341 - if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT) 1368 + if (do_sigaltstack(h2g(&frame->uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1342 goto badframe; 1369 goto badframe;
1343 1370
1344 #if 0 1371 #if 0
@@ -1788,8 +1815,8 @@ void sparc64_set_context(CPUSPARCState *env) @@ -1788,8 +1815,8 @@ void sparc64_set_context(CPUSPARCState *env)
1788 abi_ulong *src, *dst; 1815 abi_ulong *src, *dst;
1789 1816
1790 grp = &ucp->uc_mcontext.mc_gregs; 1817 grp = &ucp->uc_mcontext.mc_gregs;
1791 - err = get_user(pc, &((*grp)[MC_PC]));  
1792 - err |= get_user(npc, &((*grp)[MC_NPC])); 1818 + err = __get_user(pc, &((*grp)[MC_PC]));
  1819 + err |= __get_user(npc, &((*grp)[MC_NPC]));
1793 if (err || ((pc | npc) & 3)) 1820 if (err || ((pc | npc) & 3))
1794 goto do_sigsegv; 1821 goto do_sigsegv;
1795 if (env->regwptr[UREG_I1]) { 1822 if (env->regwptr[UREG_I1]) {
@@ -1797,14 +1824,14 @@ void sparc64_set_context(CPUSPARCState *env) @@ -1797,14 +1824,14 @@ void sparc64_set_context(CPUSPARCState *env)
1797 sigset_t set; 1824 sigset_t set;
1798 1825
1799 if (TARGET_NSIG_WORDS == 1) { 1826 if (TARGET_NSIG_WORDS == 1) {
1800 - if (get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0])) 1827 + if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
1801 goto do_sigsegv; 1828 goto do_sigsegv;
1802 } else { 1829 } else {
1803 src = &ucp->uc_sigmask; 1830 src = &ucp->uc_sigmask;
1804 dst = &target_set; 1831 dst = &target_set;
1805 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); 1832 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
1806 i++, dst++, src++) 1833 i++, dst++, src++)
1807 - err |= get_user(dst, src); 1834 + err |= __get_user(dst, src);
1808 if (err) 1835 if (err)
1809 goto do_sigsegv; 1836 goto do_sigsegv;
1810 } 1837 }
@@ -1813,44 +1840,44 @@ void sparc64_set_context(CPUSPARCState *env) @@ -1813,44 +1840,44 @@ void sparc64_set_context(CPUSPARCState *env)
1813 } 1840 }
1814 env->pc = pc; 1841 env->pc = pc;
1815 env->npc = npc; 1842 env->npc = npc;
1816 - err |= get_user(env->y, &((*grp)[MC_Y]));  
1817 - err |= get_user(tstate, &((*grp)[MC_TSTATE])); 1843 + err |= __get_user(env->y, &((*grp)[MC_Y]));
  1844 + err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
1818 env->asi = (tstate >> 24) & 0xff; 1845 env->asi = (tstate >> 24) & 0xff;
1819 PUT_CCR(env, tstate >> 32); 1846 PUT_CCR(env, tstate >> 32);
1820 PUT_CWP64(env, tstate & 0x1f); 1847 PUT_CWP64(env, tstate & 0x1f);
1821 - err |= get_user(env->gregs[1], (&(*grp)[MC_G1]));  
1822 - err |= get_user(env->gregs[2], (&(*grp)[MC_G2]));  
1823 - err |= get_user(env->gregs[3], (&(*grp)[MC_G3]));  
1824 - err |= get_user(env->gregs[4], (&(*grp)[MC_G4]));  
1825 - err |= get_user(env->gregs[5], (&(*grp)[MC_G5]));  
1826 - err |= get_user(env->gregs[6], (&(*grp)[MC_G6]));  
1827 - err |= get_user(env->gregs[7], (&(*grp)[MC_G7]));  
1828 - err |= get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));  
1829 - err |= get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));  
1830 - err |= get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));  
1831 - err |= get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));  
1832 - err |= get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));  
1833 - err |= get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));  
1834 - err |= get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));  
1835 - err |= get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));  
1836 -  
1837 - err |= get_user(fp, &(ucp->uc_mcontext.mc_fp));  
1838 - err |= get_user(i7, &(ucp->uc_mcontext.mc_i7));  
1839 - err |= put_user(fp,  
1840 - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));  
1841 - err |= put_user(i7,  
1842 - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));  
1843 -  
1844 - err |= get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));  
1845 - err |= get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs)); 1848 + err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
  1849 + err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
  1850 + err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
  1851 + err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
  1852 + err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
  1853 + err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
  1854 + err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
  1855 + err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
  1856 + err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
  1857 + err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
  1858 + err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
  1859 + err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
  1860 + err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
  1861 + err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
  1862 + err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
  1863 +
  1864 + err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
  1865 + err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
  1866 + err |= __put_user(fp,
  1867 + (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
  1868 + err |= __put_user(i7,
  1869 + (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
  1870 +
  1871 + err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
  1872 + err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
1846 src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs); 1873 src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
1847 dst = &env->fpr; 1874 dst = &env->fpr;
1848 for (i = 0; i < 64; i++, dst++, src++) 1875 for (i = 0; i < 64; i++, dst++, src++)
1849 - err |= get_user(dst, src);  
1850 - err |= get_user(env->fsr,  
1851 - &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));  
1852 - err |= get_user(env->gsr,  
1853 - &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr)); 1876 + err |= __get_user(dst, src);
  1877 + err |= __get_user(env->fsr,
  1878 + &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
  1879 + err |= __get_user(env->gsr,
  1880 + &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
1854 if (err) 1881 if (err)
1855 goto do_sigsegv; 1882 goto do_sigsegv;
1856 1883
@@ -1884,52 +1911,52 @@ void sparc64_get_context(CPUSPARCState *env) @@ -1884,52 +1911,52 @@ void sparc64_get_context(CPUSPARCState *env)
1884 sigprocmask(0, NULL, &set); 1911 sigprocmask(0, NULL, &set);
1885 host_to_target_sigset_internal(&target_set, &set); 1912 host_to_target_sigset_internal(&target_set, &set);
1886 if (TARGET_NSIG_WORDS == 1) 1913 if (TARGET_NSIG_WORDS == 1)
1887 - err |= put_user(target_set.sig[0],  
1888 - (abi_ulong *)&ucp->uc_sigmask); 1914 + err |= __put_user(target_set.sig[0],
  1915 + (abi_ulong *)&ucp->uc_sigmask);
1889 else { 1916 else {
1890 src = &target_set; 1917 src = &target_set;
1891 dst = &ucp->uc_sigmask; 1918 dst = &ucp->uc_sigmask;
1892 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); 1919 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
1893 i++, dst++, src++) 1920 i++, dst++, src++)
1894 - err |= put_user(src, dst); 1921 + err |= __put_user(src, dst);
1895 if (err) 1922 if (err)
1896 goto do_sigsegv; 1923 goto do_sigsegv;
1897 } 1924 }
1898 1925
1899 - err |= put_user(env->tstate, &((*grp)[MC_TSTATE]));  
1900 - err |= put_user(env->pc, &((*grp)[MC_PC]));  
1901 - err |= put_user(env->npc, &((*grp)[MC_NPC]));  
1902 - err |= put_user(env->y, &((*grp)[MC_Y]));  
1903 - err |= put_user(env->gregs[1], &((*grp)[MC_G1]));  
1904 - err |= put_user(env->gregs[2], &((*grp)[MC_G2]));  
1905 - err |= put_user(env->gregs[3], &((*grp)[MC_G3]));  
1906 - err |= put_user(env->gregs[4], &((*grp)[MC_G4]));  
1907 - err |= put_user(env->gregs[5], &((*grp)[MC_G5]));  
1908 - err |= put_user(env->gregs[6], &((*grp)[MC_G6]));  
1909 - err |= put_user(env->gregs[7], &((*grp)[MC_G7]));  
1910 - err |= put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));  
1911 - err |= put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));  
1912 - err |= put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));  
1913 - err |= put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));  
1914 - err |= put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));  
1915 - err |= put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));  
1916 - err |= put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));  
1917 - err |= put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));  
1918 -  
1919 - err |= get_user(fp,  
1920 - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));  
1921 - err |= get_user(i7,  
1922 - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));  
1923 - err |= put_user(fp, &(mcp->mc_fp));  
1924 - err |= put_user(i7, &(mcp->mc_i7)); 1926 + err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
  1927 + err |= __put_user(env->pc, &((*grp)[MC_PC]));
  1928 + err |= __put_user(env->npc, &((*grp)[MC_NPC]));
  1929 + err |= __put_user(env->y, &((*grp)[MC_Y]));
  1930 + err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
  1931 + err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
  1932 + err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
  1933 + err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
  1934 + err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
  1935 + err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
  1936 + err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
  1937 + err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
  1938 + err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
  1939 + err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
  1940 + err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
  1941 + err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
  1942 + err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
  1943 + err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
  1944 + err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
  1945 +
  1946 + err |= __get_user(fp,
  1947 + (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
  1948 + err |= __get_user(i7,
  1949 + (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
  1950 + err |= __put_user(fp, &(mcp->mc_fp));
  1951 + err |= __put_user(i7, &(mcp->mc_i7));
1925 1952
1926 src = &env->fpr; 1953 src = &env->fpr;
1927 dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs); 1954 dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
1928 for (i = 0; i < 64; i++, dst++, src++) 1955 for (i = 0; i < 64; i++, dst++, src++)
1929 - err |= put_user(src, dst);  
1930 - err |= put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));  
1931 - err |= put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));  
1932 - err |= put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs)); 1956 + err |= __put_user(src, dst);
  1957 + err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
  1958 + err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
  1959 + err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
1933 1960
1934 if (err) 1961 if (err)
1935 goto do_sigsegv; 1962 goto do_sigsegv;
@@ -2191,7 +2218,7 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc) @@ -2191,7 +2218,7 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2191 /* 2218 /*
2192 * Determine which stack to use.. 2219 * Determine which stack to use..
2193 */ 2220 */
2194 -static inline void * 2221 +static inline abi_ulong
2195 get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) 2222 get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
2196 { 2223 {
2197 unsigned long sp; 2224 unsigned long sp;
@@ -2211,17 +2238,19 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) @@ -2211,17 +2238,19 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
2211 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; 2238 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2212 } 2239 }
2213 2240
2214 - return g2h((sp - frame_size) & ~7); 2241 + return (sp - frame_size) & ~7;
2215 } 2242 }
2216 2243
  2244 +/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2217 static void setup_frame(int sig, struct emulated_sigaction * ka, 2245 static void setup_frame(int sig, struct emulated_sigaction * ka,
2218 - target_sigset_t *set, CPUState *regs) 2246 + target_sigset_t *set, CPUState *regs)
2219 { 2247 {
2220 struct sigframe *frame; 2248 struct sigframe *frame;
  2249 + abi_ulong frame_addr;
2221 int i; 2250 int i;
2222 2251
2223 - frame = get_sigframe(ka, regs, sizeof(*frame));  
2224 - if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 2252 + frame_addr = get_sigframe(ka, regs, sizeof(*frame));
  2253 + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2225 goto give_sigsegv; 2254 goto give_sigsegv;
2226 2255
2227 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn); 2256 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
@@ -2253,9 +2282,11 @@ static void setup_frame(int sig, struct emulated_sigaction * ka, @@ -2253,9 +2282,11 @@ static void setup_frame(int sig, struct emulated_sigaction * ka,
2253 * since it returns to userland using eret 2282 * since it returns to userland using eret
2254 * we cannot do this here, and we must set PC directly */ 2283 * we cannot do this here, and we must set PC directly */
2255 regs->PC[regs->current_tc] = regs->gpr[25][regs->current_tc] = ka->sa._sa_handler; 2284 regs->PC[regs->current_tc] = regs->gpr[25][regs->current_tc] = ka->sa._sa_handler;
  2285 + unlock_user_struct(frame, frame_addr, 1);
2256 return; 2286 return;
2257 2287
2258 give_sigsegv: 2288 give_sigsegv:
  2289 + unlock_user_struct(frame, frame_addr, 1);
2259 force_sig(TARGET_SIGSEGV/*, current*/); 2290 force_sig(TARGET_SIGSEGV/*, current*/);
2260 return; 2291 return;
2261 } 2292 }
@@ -2263,6 +2294,7 @@ give_sigsegv: @@ -2263,6 +2294,7 @@ give_sigsegv:
2263 long do_sigreturn(CPUState *regs) 2294 long do_sigreturn(CPUState *regs)
2264 { 2295 {
2265 struct sigframe *frame; 2296 struct sigframe *frame;
  2297 + abi_ulong frame_addr;
2266 sigset_t blocked; 2298 sigset_t blocked;
2267 target_sigset_t target_set; 2299 target_sigset_t target_set;
2268 int i; 2300 int i;
@@ -2270,8 +2302,8 @@ long do_sigreturn(CPUState *regs) @@ -2270,8 +2302,8 @@ long do_sigreturn(CPUState *regs)
2270 #if defined(DEBUG_SIGNAL) 2302 #if defined(DEBUG_SIGNAL)
2271 fprintf(stderr, "do_sigreturn\n"); 2303 fprintf(stderr, "do_sigreturn\n");
2272 #endif 2304 #endif
2273 - frame = (struct sigframe *) regs->gpr[29][regs->current_tc];  
2274 - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 2305 + frame_addr = regs->gpr[29][regs->current_tc];
  2306 + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2275 goto badframe; 2307 goto badframe;
2276 2308
2277 for(i = 0; i < TARGET_NSIG_WORDS; i++) { 2309 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
linux-user/strace.c
@@ -81,14 +81,18 @@ print_fdset(int n, target_ulong target_fds_addr) @@ -81,14 +81,18 @@ print_fdset(int n, target_ulong target_fds_addr)
81 81
82 gemu_log("["); 82 gemu_log("[");
83 if( target_fds_addr ) { 83 if( target_fds_addr ) {
84 - target_long *target_fds; 84 + abi_long *target_fds;
85 85
86 - if (!access_ok(VERIFY_READ, target_fds_addr, sizeof(*target_fds)*(n / TARGET_LONG_BITS + 1))) 86 + target_fds = lock_user(VERIFY_READ,
  87 + target_fds_addr,
  88 + sizeof(*target_fds)*(n / TARGET_ABI_BITS + 1),
  89 + 1);
  90 +
  91 + if (!target_fds)
87 return; 92 return;
88 93
89 - target_fds = lock_user(target_fds_addr, sizeof(*target_fds)*(n / TARGET_LONG_BITS + 1), 1);  
90 for (i=n; i>=0; i--) { 94 for (i=n; i>=0; i--) {
91 - if ((tswapl(target_fds[i / TARGET_LONG_BITS]) >> (i & (TARGET_LONG_BITS - 1))) & 1) 95 + if ((tswapl(target_fds[i / TARGET_ABI_BITS]) >> (i & (TARGET_ABI_BITS - 1))) & 1)
92 gemu_log("%d,", i ); 96 gemu_log("%d,", i );
93 } 97 }
94 unlock_user(target_fds, target_fds_addr, 0); 98 unlock_user(target_fds, target_fds_addr, 0);
@@ -102,10 +106,9 @@ print_timeval(target_ulong tv_addr) @@ -102,10 +106,9 @@ print_timeval(target_ulong tv_addr)
102 if( tv_addr ) { 106 if( tv_addr ) {
103 struct target_timeval *tv; 107 struct target_timeval *tv;
104 108
105 - if (!access_ok(VERIFY_READ, tv_addr, sizeof(*tv))) 109 + tv = lock_user(VERIFY_READ, tv_addr, sizeof(*tv), 1);
  110 + if (!tv)
106 return; 111 return;
107 -  
108 - tv = lock_user(tv_addr, sizeof(*tv), 1);  
109 gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}", 112 gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}",
110 tv->tv_sec, tv->tv_usec); 113 tv->tv_sec, tv->tv_usec);
111 unlock_user(tv, tv_addr, 0); 114 unlock_user(tv, tv_addr, 0);
@@ -165,27 +168,25 @@ print_execve(struct syscallname *name, @@ -165,27 +168,25 @@ print_execve(struct syscallname *name,
165 target_ulong arg_ptr_addr; 168 target_ulong arg_ptr_addr;
166 char *s; 169 char *s;
167 170
168 - if (!access_ok(VERIFY_READ, arg1, 1)) 171 + if (!(s = lock_user_string(arg1)))
169 return; 172 return;
170 -  
171 - s = lock_user_string(arg1);  
172 gemu_log("%s(\"%s\",{", name->name, s); 173 gemu_log("%s(\"%s\",{", name->name, s);
173 unlock_user(s, arg1, 0); 174 unlock_user(s, arg1, 0);
174 175
175 for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(target_ulong)) { 176 for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(target_ulong)) {
176 target_ulong *arg_ptr, arg_addr, s_addr; 177 target_ulong *arg_ptr, arg_addr, s_addr;
177 178
178 - if (!access_ok(VERIFY_READ, arg_ptr_addr, sizeof(target_ulong))) 179 + arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(target_ulong), 1);
  180 + if (!arg_ptr)
179 return; 181 return;
180 -  
181 - arg_ptr = lock_user(arg_ptr_addr, sizeof(target_ulong), 1);  
182 arg_addr = tswapl(*arg_ptr); 182 arg_addr = tswapl(*arg_ptr);
183 unlock_user(arg_ptr, arg_ptr_addr, 0); 183 unlock_user(arg_ptr, arg_ptr_addr, 0);
184 if (!arg_addr) 184 if (!arg_addr)
185 break; 185 break;
186 - s = lock_user_string(arg_addr);  
187 - gemu_log("\"%s\",", s);  
188 - unlock_user(s, s_addr, 0); 186 + if ((s = lock_user_string(arg_addr))) {
  187 + gemu_log("\"%s\",", s);
  188 + unlock_user(s, s_addr, 0);
  189 + }
189 } 190 }
190 191
191 gemu_log("NULL})"); 192 gemu_log("NULL})");
linux-user/syscall.c
@@ -504,12 +504,13 @@ static inline abi_long host_to_target_clock_t(long ticks) @@ -504,12 +504,13 @@ static inline abi_long host_to_target_clock_t(long ticks)
504 #endif 504 #endif
505 } 505 }
506 506
507 -static inline void host_to_target_rusage(abi_ulong target_addr,  
508 - const struct rusage *rusage) 507 +static inline abi_long host_to_target_rusage(abi_ulong target_addr,
  508 + const struct rusage *rusage)
509 { 509 {
510 struct target_rusage *target_rusage; 510 struct target_rusage *target_rusage;
511 511
512 - lock_user_struct(target_rusage, target_addr, 0); 512 + if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
  513 + return -TARGET_EFAULT;
513 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec); 514 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
514 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec); 515 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
515 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec); 516 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
@@ -529,28 +530,36 @@ static inline void host_to_target_rusage(abi_ulong target_addr, @@ -529,28 +530,36 @@ static inline void host_to_target_rusage(abi_ulong target_addr,
529 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw); 530 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
530 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw); 531 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
531 unlock_user_struct(target_rusage, target_addr, 1); 532 unlock_user_struct(target_rusage, target_addr, 1);
  533 +
  534 + return 0;
532 } 535 }
533 536
534 -static inline void target_to_host_timeval(struct timeval *tv,  
535 - abi_ulong target_addr) 537 +static inline abi_long target_to_host_timeval(struct timeval *tv,
  538 + abi_ulong target_addr)
536 { 539 {
537 struct target_timeval *target_tv; 540 struct target_timeval *target_tv;
538 541
539 - lock_user_struct(target_tv, target_addr, 1); 542 + if (!lock_user_struct(VERIFY_READ, target_tv, target_addr, 1))
  543 + return -TARGET_EFAULT;
540 tv->tv_sec = tswapl(target_tv->tv_sec); 544 tv->tv_sec = tswapl(target_tv->tv_sec);
541 tv->tv_usec = tswapl(target_tv->tv_usec); 545 tv->tv_usec = tswapl(target_tv->tv_usec);
542 unlock_user_struct(target_tv, target_addr, 0); 546 unlock_user_struct(target_tv, target_addr, 0);
  547 +
  548 + return 0;
543 } 549 }
544 550
545 -static inline void host_to_target_timeval(abi_ulong target_addr,  
546 - const struct timeval *tv) 551 +static inline abi_long host_to_target_timeval(abi_ulong target_addr,
  552 + const struct timeval *tv)
547 { 553 {
548 struct target_timeval *target_tv; 554 struct target_timeval *target_tv;
549 555
550 - lock_user_struct(target_tv, target_addr, 0); 556 + if (!lock_user_struct(VERIFY_WRITE, target_tv, target_addr, 0))
  557 + return -TARGET_EFAULT;
551 target_tv->tv_sec = tswapl(tv->tv_sec); 558 target_tv->tv_sec = tswapl(tv->tv_sec);
552 target_tv->tv_usec = tswapl(tv->tv_usec); 559 target_tv->tv_usec = tswapl(tv->tv_usec);
553 unlock_user_struct(target_tv, target_addr, 1); 560 unlock_user_struct(target_tv, target_addr, 1);
  561 +
  562 + return 0;
554 } 563 }
555 564
556 565
@@ -567,21 +576,33 @@ static abi_long do_select(int n, @@ -567,21 +576,33 @@ static abi_long do_select(int n,
567 int ok; 576 int ok;
568 577
569 if (rfd_p) { 578 if (rfd_p) {
570 - target_rfds = lock_user(rfd_p, sizeof(abi_long) * n, 1); 579 + target_rfds = lock_user(VERIFY_WRITE, rfd_p, sizeof(abi_long) * n, 1);
  580 + if (!target_rfds) {
  581 + ret = -TARGET_EFAULT;
  582 + goto end;
  583 + }
571 rfds_ptr = target_to_host_fds(&rfds, target_rfds, n); 584 rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
572 } else { 585 } else {
573 target_rfds = NULL; 586 target_rfds = NULL;
574 rfds_ptr = NULL; 587 rfds_ptr = NULL;
575 } 588 }
576 if (wfd_p) { 589 if (wfd_p) {
577 - target_wfds = lock_user(wfd_p, sizeof(abi_long) * n, 1); 590 + target_wfds = lock_user(VERIFY_WRITE, wfd_p, sizeof(abi_long) * n, 1);
  591 + if (!target_wfds) {
  592 + ret = -TARGET_EFAULT;
  593 + goto end;
  594 + }
578 wfds_ptr = target_to_host_fds(&wfds, target_wfds, n); 595 wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
579 } else { 596 } else {
580 target_wfds = NULL; 597 target_wfds = NULL;
581 wfds_ptr = NULL; 598 wfds_ptr = NULL;
582 } 599 }
583 if (efd_p) { 600 if (efd_p) {
584 - target_efds = lock_user(efd_p, sizeof(abi_long) * n, 1); 601 + target_efds = lock_user(VERIFY_WRITE, efd_p, sizeof(abi_long) * n, 1);
  602 + if (!target_efds) {
  603 + ret = -TARGET_EFAULT;
  604 + goto end;
  605 + }
585 efds_ptr = target_to_host_fds(&efds, target_efds, n); 606 efds_ptr = target_to_host_fds(&efds, target_efds, n);
586 } else { 607 } else {
587 target_efds = NULL; 608 target_efds = NULL;
@@ -606,38 +627,45 @@ static abi_long do_select(int n, @@ -606,38 +627,45 @@ static abi_long do_select(int n,
606 host_to_target_timeval(target_tv, &tv); 627 host_to_target_timeval(target_tv, &tv);
607 } 628 }
608 } 629 }
609 - if (target_rfds)  
610 - unlock_user(target_rfds, rfd_p, ok ? sizeof(abi_long) * n : 0);  
611 - if (target_wfds)  
612 - unlock_user(target_wfds, wfd_p, ok ? sizeof(abi_long) * n : 0);  
613 - if (target_efds)  
614 - unlock_user(target_efds, efd_p, ok ? sizeof(abi_long) * n : 0); 630 +
  631 +end:
  632 + unlock_user(target_rfds, rfd_p, ok ? sizeof(abi_long) * n : 0);
  633 + unlock_user(target_wfds, wfd_p, ok ? sizeof(abi_long) * n : 0);
  634 + unlock_user(target_efds, efd_p, ok ? sizeof(abi_long) * n : 0);
615 635
616 return ret; 636 return ret;
617 } 637 }
618 638
619 -static inline void target_to_host_sockaddr(struct sockaddr *addr,  
620 - abi_ulong target_addr,  
621 - socklen_t len) 639 +static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
  640 + abi_ulong target_addr,
  641 + socklen_t len)
622 { 642 {
623 struct target_sockaddr *target_saddr; 643 struct target_sockaddr *target_saddr;
624 644
625 - target_saddr = lock_user(target_addr, len, 1); 645 + target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
  646 + if (!target_saddr)
  647 + return -TARGET_EFAULT;
626 memcpy(addr, target_saddr, len); 648 memcpy(addr, target_saddr, len);
627 addr->sa_family = tswap16(target_saddr->sa_family); 649 addr->sa_family = tswap16(target_saddr->sa_family);
628 unlock_user(target_saddr, target_addr, 0); 650 unlock_user(target_saddr, target_addr, 0);
  651 +
  652 + return 0;
629 } 653 }
630 654
631 -static inline void host_to_target_sockaddr(abi_ulong target_addr,  
632 - struct sockaddr *addr,  
633 - socklen_t len) 655 +static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
  656 + struct sockaddr *addr,
  657 + socklen_t len)
634 { 658 {
635 struct target_sockaddr *target_saddr; 659 struct target_sockaddr *target_saddr;
636 660
637 - target_saddr = lock_user(target_addr, len, 0); 661 + target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
  662 + if (!target_saddr)
  663 + return -TARGET_EFAULT;
638 memcpy(target_saddr, addr, len); 664 memcpy(target_saddr, addr, len);
639 target_saddr->sa_family = tswap16(addr->sa_family); 665 target_saddr->sa_family = tswap16(addr->sa_family);
640 unlock_user(target_saddr, target_addr, len); 666 unlock_user(target_saddr, target_addr, len);
  667 +
  668 + return 0;
641 } 669 }
642 670
643 /* ??? Should this also swap msgh->name? */ 671 /* ??? Should this also swap msgh->name? */
@@ -941,35 +969,56 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, @@ -941,35 +969,56 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
941 return ret; 969 return ret;
942 } 970 }
943 971
944 -static void lock_iovec(struct iovec *vec, abi_ulong target_addr,  
945 - int count, int copy) 972 +/* FIXME
  973 + * lock_iovec()/unlock_iovec() have a return code of 0 for success where
  974 + * other lock functions have a return code of 0 for failure.
  975 + */
  976 +static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
  977 + int count, int copy)
946 { 978 {
947 struct target_iovec *target_vec; 979 struct target_iovec *target_vec;
948 abi_ulong base; 980 abi_ulong base;
949 - int i; 981 + int i, j;
950 982
951 - target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); 983 + target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
  984 + if (!target_vec)
  985 + return -TARGET_EFAULT;
952 for(i = 0;i < count; i++) { 986 for(i = 0;i < count; i++) {
953 base = tswapl(target_vec[i].iov_base); 987 base = tswapl(target_vec[i].iov_base);
954 vec[i].iov_len = tswapl(target_vec[i].iov_len); 988 vec[i].iov_len = tswapl(target_vec[i].iov_len);
955 - vec[i].iov_base = lock_user(base, vec[i].iov_len, copy); 989 + vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
  990 + if (!vec[i].iov_base)
  991 + goto fail;
  992 + }
  993 + unlock_user (target_vec, target_addr, 0);
  994 + return 0;
  995 + fail:
  996 + /* failure - unwind locks */
  997 + for (j = 0; j < i; j++) {
  998 + base = tswapl(target_vec[j].iov_base);
  999 + unlock_user(vec[j].iov_base, base, 0);
956 } 1000 }
957 unlock_user (target_vec, target_addr, 0); 1001 unlock_user (target_vec, target_addr, 0);
  1002 + return -TARGET_EFAULT;
958 } 1003 }
959 1004
960 -static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,  
961 - int count, int copy) 1005 +static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
  1006 + int count, int copy)
962 { 1007 {
963 struct target_iovec *target_vec; 1008 struct target_iovec *target_vec;
964 abi_ulong base; 1009 abi_ulong base;
965 int i; 1010 int i;
966 1011
967 - target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); 1012 + target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
  1013 + if (!target_vec)
  1014 + return -TARGET_EFAULT;
968 for(i = 0;i < count; i++) { 1015 for(i = 0;i < count; i++) {
969 base = tswapl(target_vec[i].iov_base); 1016 base = tswapl(target_vec[i].iov_base);
970 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); 1017 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
971 } 1018 }
972 unlock_user (target_vec, target_addr, 0); 1019 unlock_user (target_vec, target_addr, 0);
  1020 +
  1021 + return 0;
973 } 1022 }
974 1023
975 /* do_socket() Must return target values and target errnos. */ 1024 /* do_socket() Must return target values and target errnos. */
@@ -1033,7 +1082,12 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, @@ -1033,7 +1082,12 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1033 struct iovec *vec; 1082 struct iovec *vec;
1034 abi_ulong target_vec; 1083 abi_ulong target_vec;
1035 1084
1036 - lock_user_struct(msgp, target_msg, 1); 1085 + /* FIXME */
  1086 + if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
  1087 + msgp,
  1088 + target_msg,
  1089 + send ? 1 : 0))
  1090 + return -TARGET_EFAULT;
1037 if (msgp->msg_name) { 1091 if (msgp->msg_name) {
1038 msg.msg_namelen = tswap32(msgp->msg_namelen); 1092 msg.msg_namelen = tswap32(msgp->msg_namelen);
1039 msg.msg_name = alloca(msg.msg_namelen); 1093 msg.msg_name = alloca(msg.msg_namelen);
@@ -1050,7 +1104,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, @@ -1050,7 +1104,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1050 count = tswapl(msgp->msg_iovlen); 1104 count = tswapl(msgp->msg_iovlen);
1051 vec = alloca(count * sizeof(struct iovec)); 1105 vec = alloca(count * sizeof(struct iovec));
1052 target_vec = tswapl(msgp->msg_iov); 1106 target_vec = tswapl(msgp->msg_iov);
1053 - lock_iovec(vec, target_vec, count, send); 1107 + lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1054 msg.msg_iovlen = count; 1108 msg.msg_iovlen = count;
1055 msg.msg_iov = vec; 1109 msg.msg_iov = vec;
1056 1110
@@ -1063,6 +1117,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, @@ -1063,6 +1117,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1063 host_to_target_cmsg(msgp, &msg); 1117 host_to_target_cmsg(msgp, &msg);
1064 } 1118 }
1065 unlock_iovec(vec, target_vec, count, !send); 1119 unlock_iovec(vec, target_vec, count, !send);
  1120 + unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1066 return ret; 1121 return ret;
1067 } 1122 }
1068 1123
@@ -1137,7 +1192,9 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, @@ -1137,7 +1192,9 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1137 void *host_msg; 1192 void *host_msg;
1138 abi_long ret; 1193 abi_long ret;
1139 1194
1140 - host_msg = lock_user(msg, len, 1); 1195 + host_msg = lock_user(VERIFY_READ, msg, len, 1);
  1196 + if (!host_msg)
  1197 + return -TARGET_EFAULT;
1141 if (target_addr) { 1198 if (target_addr) {
1142 addr = alloca(addrlen); 1199 addr = alloca(addrlen);
1143 target_to_host_sockaddr(addr, target_addr, addrlen); 1200 target_to_host_sockaddr(addr, target_addr, addrlen);
@@ -1159,7 +1216,9 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, @@ -1159,7 +1216,9 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1159 void *host_msg; 1216 void *host_msg;
1160 abi_long ret; 1217 abi_long ret;
1161 1218
1162 - host_msg = lock_user(msg, len, 0); 1219 + host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
  1220 + if (!host_msg)
  1221 + return -TARGET_EFAULT;
1163 if (target_addr) { 1222 if (target_addr) {
1164 addrlen = tget32(target_addrlen); 1223 addrlen = tget32(target_addrlen);
1165 addr = alloca(addrlen); 1224 addr = alloca(addrlen);
@@ -1381,13 +1440,14 @@ struct target_semid_ds @@ -1381,13 +1440,14 @@ struct target_semid_ds
1381 abi_ulong __unused4; 1440 abi_ulong __unused4;
1382 }; 1441 };
1383 1442
1384 -static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,  
1385 - abi_ulong target_addr) 1443 +static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
  1444 + abi_ulong target_addr)
1386 { 1445 {
1387 struct target_ipc_perm *target_ip; 1446 struct target_ipc_perm *target_ip;
1388 struct target_semid_ds *target_sd; 1447 struct target_semid_ds *target_sd;
1389 1448
1390 - lock_user_struct(target_sd, target_addr, 1); 1449 + if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
  1450 + return -TARGET_EFAULT;
1391 target_ip=&(target_sd->sem_perm); 1451 target_ip=&(target_sd->sem_perm);
1392 host_ip->__key = tswapl(target_ip->__key); 1452 host_ip->__key = tswapl(target_ip->__key);
1393 host_ip->uid = tswapl(target_ip->uid); 1453 host_ip->uid = tswapl(target_ip->uid);
@@ -1396,15 +1456,17 @@ static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip, @@ -1396,15 +1456,17 @@ static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,
1396 host_ip->cgid = tswapl(target_ip->cgid); 1456 host_ip->cgid = tswapl(target_ip->cgid);
1397 host_ip->mode = tswapl(target_ip->mode); 1457 host_ip->mode = tswapl(target_ip->mode);
1398 unlock_user_struct(target_sd, target_addr, 0); 1458 unlock_user_struct(target_sd, target_addr, 0);
  1459 + return 0;
1399 } 1460 }
1400 1461
1401 -static inline void host_to_target_ipc_perm(abi_ulong target_addr,  
1402 - struct ipc_perm *host_ip) 1462 +static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
  1463 + struct ipc_perm *host_ip)
1403 { 1464 {
1404 struct target_ipc_perm *target_ip; 1465 struct target_ipc_perm *target_ip;
1405 struct target_semid_ds *target_sd; 1466 struct target_semid_ds *target_sd;
1406 1467
1407 - lock_user_struct(target_sd, target_addr, 0); 1468 + if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
  1469 + return -TARGET_EFAULT;
1408 target_ip = &(target_sd->sem_perm); 1470 target_ip = &(target_sd->sem_perm);
1409 target_ip->__key = tswapl(host_ip->__key); 1471 target_ip->__key = tswapl(host_ip->__key);
1410 target_ip->uid = tswapl(host_ip->uid); 1472 target_ip->uid = tswapl(host_ip->uid);
@@ -1413,32 +1475,37 @@ static inline void host_to_target_ipc_perm(abi_ulong target_addr, @@ -1413,32 +1475,37 @@ static inline void host_to_target_ipc_perm(abi_ulong target_addr,
1413 target_ip->cgid = tswapl(host_ip->cgid); 1475 target_ip->cgid = tswapl(host_ip->cgid);
1414 target_ip->mode = tswapl(host_ip->mode); 1476 target_ip->mode = tswapl(host_ip->mode);
1415 unlock_user_struct(target_sd, target_addr, 1); 1477 unlock_user_struct(target_sd, target_addr, 1);
  1478 + return 0;
1416 } 1479 }
1417 1480
1418 -static inline void target_to_host_semid_ds(struct semid_ds *host_sd,  
1419 - abi_ulong target_addr) 1481 +static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
  1482 + abi_ulong target_addr)
1420 { 1483 {
1421 struct target_semid_ds *target_sd; 1484 struct target_semid_ds *target_sd;
1422 1485
1423 - lock_user_struct(target_sd, target_addr, 1); 1486 + if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
  1487 + return -TARGET_EFAULT;
1424 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr); 1488 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1425 host_sd->sem_nsems = tswapl(target_sd->sem_nsems); 1489 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1426 host_sd->sem_otime = tswapl(target_sd->sem_otime); 1490 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1427 host_sd->sem_ctime = tswapl(target_sd->sem_ctime); 1491 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1428 unlock_user_struct(target_sd, target_addr, 0); 1492 unlock_user_struct(target_sd, target_addr, 0);
  1493 + return 0;
1429 } 1494 }
1430 1495
1431 -static inline void host_to_target_semid_ds(abi_ulong target_addr,  
1432 - struct semid_ds *host_sd) 1496 +static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
  1497 + struct semid_ds *host_sd)
1433 { 1498 {
1434 struct target_semid_ds *target_sd; 1499 struct target_semid_ds *target_sd;
1435 1500
1436 - lock_user_struct(target_sd, target_addr, 0); 1501 + if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
  1502 + return -TARGET_EFAULT;
1437 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)); 1503 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1438 target_sd->sem_nsems = tswapl(host_sd->sem_nsems); 1504 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1439 target_sd->sem_otime = tswapl(host_sd->sem_otime); 1505 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1440 target_sd->sem_ctime = tswapl(host_sd->sem_ctime); 1506 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1441 unlock_user_struct(target_sd, target_addr, 1); 1507 unlock_user_struct(target_sd, target_addr, 1);
  1508 + return 0;
1442 } 1509 }
1443 1510
1444 union semun { 1511 union semun {
@@ -1453,67 +1520,75 @@ union target_semun { @@ -1453,67 +1520,75 @@ union target_semun {
1453 unsigned short int *array; 1520 unsigned short int *array;
1454 }; 1521 };
1455 1522
1456 -static inline void target_to_host_semun(int cmd,  
1457 - union semun *host_su,  
1458 - abi_ulong target_addr,  
1459 - struct semid_ds *ds) 1523 +static inline abi_long target_to_host_semun(int cmd,
  1524 + union semun *host_su,
  1525 + abi_ulong target_addr,
  1526 + struct semid_ds *ds)
1460 { 1527 {
1461 union target_semun *target_su; 1528 union target_semun *target_su;
1462 1529
1463 switch( cmd ) { 1530 switch( cmd ) {
1464 case IPC_STAT: 1531 case IPC_STAT:
1465 case IPC_SET: 1532 case IPC_SET:
1466 - lock_user_struct(target_su, target_addr, 1); 1533 + if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
  1534 + return -TARGET_EFAULT;
1467 target_to_host_semid_ds(ds,target_su->buf); 1535 target_to_host_semid_ds(ds,target_su->buf);
1468 host_su->buf = ds; 1536 host_su->buf = ds;
1469 unlock_user_struct(target_su, target_addr, 0); 1537 unlock_user_struct(target_su, target_addr, 0);
1470 break; 1538 break;
1471 case GETVAL: 1539 case GETVAL:
1472 case SETVAL: 1540 case SETVAL:
1473 - lock_user_struct(target_su, target_addr, 1); 1541 + if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
  1542 + return -TARGET_EFAULT;
1474 host_su->val = tswapl(target_su->val); 1543 host_su->val = tswapl(target_su->val);
1475 unlock_user_struct(target_su, target_addr, 0); 1544 unlock_user_struct(target_su, target_addr, 0);
1476 break; 1545 break;
1477 case GETALL: 1546 case GETALL:
1478 case SETALL: 1547 case SETALL:
1479 - lock_user_struct(target_su, target_addr, 1); 1548 + if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
  1549 + return -TARGET_EFAULT;
1480 *host_su->array = tswap16(*target_su->array); 1550 *host_su->array = tswap16(*target_su->array);
1481 unlock_user_struct(target_su, target_addr, 0); 1551 unlock_user_struct(target_su, target_addr, 0);
1482 break; 1552 break;
1483 default: 1553 default:
1484 gemu_log("semun operation not fully supported: %d\n", (int)cmd); 1554 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1485 } 1555 }
  1556 + return 0;
1486 } 1557 }
1487 1558
1488 -static inline void host_to_target_semun(int cmd,  
1489 - abi_ulong target_addr,  
1490 - union semun *host_su,  
1491 - struct semid_ds *ds) 1559 +static inline abi_long host_to_target_semun(int cmd,
  1560 + abi_ulong target_addr,
  1561 + union semun *host_su,
  1562 + struct semid_ds *ds)
1492 { 1563 {
1493 union target_semun *target_su; 1564 union target_semun *target_su;
1494 1565
1495 switch( cmd ) { 1566 switch( cmd ) {
1496 case IPC_STAT: 1567 case IPC_STAT:
1497 case IPC_SET: 1568 case IPC_SET:
1498 - lock_user_struct(target_su, target_addr, 0); 1569 + if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
  1570 + return -TARGET_EFAULT;
1499 host_to_target_semid_ds(target_su->buf,ds); 1571 host_to_target_semid_ds(target_su->buf,ds);
1500 unlock_user_struct(target_su, target_addr, 1); 1572 unlock_user_struct(target_su, target_addr, 1);
1501 break; 1573 break;
1502 case GETVAL: 1574 case GETVAL:
1503 case SETVAL: 1575 case SETVAL:
1504 - lock_user_struct(target_su, target_addr, 0); 1576 + if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
  1577 + return -TARGET_EFAULT;
1505 target_su->val = tswapl(host_su->val); 1578 target_su->val = tswapl(host_su->val);
1506 unlock_user_struct(target_su, target_addr, 1); 1579 unlock_user_struct(target_su, target_addr, 1);
1507 break; 1580 break;
1508 case GETALL: 1581 case GETALL:
1509 case SETALL: 1582 case SETALL:
1510 - lock_user_struct(target_su, target_addr, 0); 1583 + if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
  1584 + return -TARGET_EFAULT;
1511 *target_su->array = tswap16(*host_su->array); 1585 *target_su->array = tswap16(*host_su->array);
1512 unlock_user_struct(target_su, target_addr, 1); 1586 unlock_user_struct(target_su, target_addr, 1);
1513 break; 1587 break;
1514 default: 1588 default:
1515 gemu_log("semun operation not fully supported: %d\n", (int)cmd); 1589 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1516 } 1590 }
  1591 + return 0;
1517 } 1592 }
1518 1593
1519 static inline abi_long do_semctl(int first, int second, int third, 1594 static inline abi_long do_semctl(int first, int second, int third,
@@ -1580,12 +1655,13 @@ struct target_msqid_ds @@ -1580,12 +1655,13 @@ struct target_msqid_ds
1580 abi_ulong __unused5; 1655 abi_ulong __unused5;
1581 }; 1656 };
1582 1657
1583 -static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,  
1584 - abi_ulong target_addr) 1658 +static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
  1659 + abi_ulong target_addr)
1585 { 1660 {
1586 struct target_msqid_ds *target_md; 1661 struct target_msqid_ds *target_md;
1587 1662
1588 - lock_user_struct(target_md, target_addr, 1); 1663 + if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
  1664 + return -TARGET_EFAULT;
1589 target_to_host_ipc_perm(&(host_md->msg_perm),target_addr); 1665 target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1590 host_md->msg_stime = tswapl(target_md->msg_stime); 1666 host_md->msg_stime = tswapl(target_md->msg_stime);
1591 host_md->msg_rtime = tswapl(target_md->msg_rtime); 1667 host_md->msg_rtime = tswapl(target_md->msg_rtime);
@@ -1596,14 +1672,16 @@ static inline void target_to_host_msqid_ds(struct msqid_ds *host_md, @@ -1596,14 +1672,16 @@ static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
1596 host_md->msg_lspid = tswapl(target_md->msg_lspid); 1672 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1597 host_md->msg_lrpid = tswapl(target_md->msg_lrpid); 1673 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1598 unlock_user_struct(target_md, target_addr, 0); 1674 unlock_user_struct(target_md, target_addr, 0);
  1675 + return 0;
1599 } 1676 }
1600 1677
1601 -static inline void host_to_target_msqid_ds(abi_ulong target_addr,  
1602 - struct msqid_ds *host_md) 1678 +static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
  1679 + struct msqid_ds *host_md)
1603 { 1680 {
1604 struct target_msqid_ds *target_md; 1681 struct target_msqid_ds *target_md;
1605 1682
1606 - lock_user_struct(target_md, target_addr, 0); 1683 + if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
  1684 + return -TARGET_EFAULT;
1607 host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)); 1685 host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1608 target_md->msg_stime = tswapl(host_md->msg_stime); 1686 target_md->msg_stime = tswapl(host_md->msg_stime);
1609 target_md->msg_rtime = tswapl(host_md->msg_rtime); 1687 target_md->msg_rtime = tswapl(host_md->msg_rtime);
@@ -1614,6 +1692,7 @@ static inline void host_to_target_msqid_ds(abi_ulong target_addr, @@ -1614,6 +1692,7 @@ static inline void host_to_target_msqid_ds(abi_ulong target_addr,
1614 target_md->msg_lspid = tswapl(host_md->msg_lspid); 1692 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1615 target_md->msg_lrpid = tswapl(host_md->msg_lrpid); 1693 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1616 unlock_user_struct(target_md, target_addr, 1); 1694 unlock_user_struct(target_md, target_addr, 1);
  1695 + return 0;
1617 } 1696 }
1618 1697
1619 static inline abi_long do_msgctl(int first, int second, abi_long ptr) 1698 static inline abi_long do_msgctl(int first, int second, abi_long ptr)
@@ -1645,7 +1724,8 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp, @@ -1645,7 +1724,8 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1645 struct msgbuf *host_mb; 1724 struct msgbuf *host_mb;
1646 abi_long ret = 0; 1725 abi_long ret = 0;
1647 1726
1648 - lock_user_struct(target_mb,msgp,0); 1727 + if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
  1728 + return -TARGET_EFAULT;
1649 host_mb = malloc(msgsz+sizeof(long)); 1729 host_mb = malloc(msgsz+sizeof(long));
1650 host_mb->mtype = tswapl(target_mb->mtype); 1730 host_mb->mtype = tswapl(target_mb->mtype);
1651 memcpy(host_mb->mtext,target_mb->mtext,msgsz); 1731 memcpy(host_mb->mtext,target_mb->mtext,msgsz);
@@ -1661,18 +1741,30 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp, @@ -1661,18 +1741,30 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1661 int msgflg) 1741 int msgflg)
1662 { 1742 {
1663 struct target_msgbuf *target_mb; 1743 struct target_msgbuf *target_mb;
  1744 + char *target_mtext;
1664 struct msgbuf *host_mb; 1745 struct msgbuf *host_mb;
1665 abi_long ret = 0; 1746 abi_long ret = 0;
1666 1747
1667 - lock_user_struct(target_mb, msgp, 0); 1748 + if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
  1749 + return -TARGET_EFAULT;
1668 host_mb = malloc(msgsz+sizeof(long)); 1750 host_mb = malloc(msgsz+sizeof(long));
1669 ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg)); 1751 ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1670 - if (ret > 0) 1752 + if (ret > 0) {
  1753 + abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
  1754 + target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
  1755 + if (!target_mtext) {
  1756 + ret = -TARGET_EFAULT;
  1757 + goto end;
  1758 + }
1671 memcpy(target_mb->mtext, host_mb->mtext, ret); 1759 memcpy(target_mb->mtext, host_mb->mtext, ret);
  1760 + unlock_user(target_mtext, target_mtext_addr, ret);
  1761 + }
1672 target_mb->mtype = tswapl(host_mb->mtype); 1762 target_mb->mtype = tswapl(host_mb->mtype);
1673 free(host_mb); 1763 free(host_mb);
1674 - unlock_user_struct(target_mb, msgp, 0);  
1675 1764
  1765 +end:
  1766 + if (target_mb)
  1767 + unlock_user_struct(target_mb, msgp, 1);
1676 return ret; 1768 return ret;
1677 } 1769 }
1678 1770
@@ -1693,7 +1785,7 @@ static abi_long do_ipc(unsigned int call, int first, @@ -1693,7 +1785,7 @@ static abi_long do_ipc(unsigned int call, int first,
1693 1785
1694 switch (call) { 1786 switch (call) {
1695 case IPCOP_semop: 1787 case IPCOP_semop:
1696 - ret = get_errno(semop(first,(struct sembuf *) ptr, second)); 1788 + ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1697 break; 1789 break;
1698 1790
1699 case IPCOP_semget: 1791 case IPCOP_semget:
@@ -1723,13 +1815,14 @@ static abi_long do_ipc(unsigned int call, int first, @@ -1723,13 +1815,14 @@ static abi_long do_ipc(unsigned int call, int first,
1723 1815
1724 case IPCOP_msgrcv: 1816 case IPCOP_msgrcv:
1725 { 1817 {
  1818 + /* XXX: this code is not correct */
1726 struct ipc_kludge 1819 struct ipc_kludge
1727 { 1820 {
1728 void *__unbounded msgp; 1821 void *__unbounded msgp;
1729 long int msgtyp; 1822 long int msgtyp;
1730 }; 1823 };
1731 1824
1732 - struct ipc_kludge *foo = (struct ipc_kludge *) ptr; 1825 + struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
1733 struct msgbuf *msgp = (struct msgbuf *) foo->msgp; 1826 struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
1734 1827
1735 ret = do_msgrcv(first, (long)msgp, second, 0, third); 1828 ret = do_msgrcv(first, (long)msgp, second, 0, third);
@@ -1761,7 +1854,7 @@ static abi_long do_ipc(unsigned int call, int first, @@ -1761,7 +1854,7 @@ static abi_long do_ipc(unsigned int call, int first,
1761 break; 1854 break;
1762 } 1855 }
1763 } 1856 }
1764 - if (put_user(raddr, (abi_ulong *)third)) 1857 + if (put_user(raddr, third, abi_ulong))
1765 return -TARGET_EFAULT; 1858 return -TARGET_EFAULT;
1766 ret = 0; 1859 ret = 0;
1767 break; 1860 break;
@@ -1883,25 +1976,33 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) @@ -1883,25 +1976,33 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
1883 case IOC_R: 1976 case IOC_R:
1884 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 1977 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1885 if (!is_error(ret)) { 1978 if (!is_error(ret)) {
1886 - argptr = lock_user(arg, target_size, 0); 1979 + argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
  1980 + if (!argptr)
  1981 + return -TARGET_EFAULT;
1887 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); 1982 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
1888 unlock_user(argptr, arg, target_size); 1983 unlock_user(argptr, arg, target_size);
1889 } 1984 }
1890 break; 1985 break;
1891 case IOC_W: 1986 case IOC_W:
1892 - argptr = lock_user(arg, target_size, 1); 1987 + argptr = lock_user(VERIFY_READ, arg, target_size, 1);
  1988 + if (!argptr)
  1989 + return -TARGET_EFAULT;
1893 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); 1990 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
1894 unlock_user(argptr, arg, 0); 1991 unlock_user(argptr, arg, 0);
1895 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 1992 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1896 break; 1993 break;
1897 default: 1994 default:
1898 case IOC_RW: 1995 case IOC_RW:
1899 - argptr = lock_user(arg, target_size, 1); 1996 + argptr = lock_user(VERIFY_READ, arg, target_size, 1);
  1997 + if (!argptr)
  1998 + return -TARGET_EFAULT;
1900 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); 1999 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
1901 unlock_user(argptr, arg, 0); 2000 unlock_user(argptr, arg, 0);
1902 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 2001 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1903 if (!is_error(ret)) { 2002 if (!is_error(ret)) {
1904 - argptr = lock_user(arg, target_size, 0); 2003 + argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
  2004 + if (!argptr)
  2005 + return -TARGET_EFAULT;
1905 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); 2006 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
1906 unlock_user(argptr, arg, target_size); 2007 unlock_user(argptr, arg, target_size);
1907 } 2008 }
@@ -2138,8 +2239,10 @@ static int read_ldt(abi_ulong ptr, unsigned long bytecount) @@ -2138,8 +2239,10 @@ static int read_ldt(abi_ulong ptr, unsigned long bytecount)
2138 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE; 2239 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2139 if (size > bytecount) 2240 if (size > bytecount)
2140 size = bytecount; 2241 size = bytecount;
2141 - p = lock_user(ptr, size, 0);  
2142 - /* ??? Shoudl this by byteswapped? */ 2242 + p = lock_user(VERIFY_WRITE, ptr, size, 0);
  2243 + if (!p)
  2244 + return -EFAULT;
  2245 + /* ??? Should this by byteswapped? */
2143 memcpy(p, ldt_table, size); 2246 memcpy(p, ldt_table, size);
2144 unlock_user(p, ptr, size); 2247 unlock_user(p, ptr, size);
2145 return size; 2248 return size;
@@ -2158,7 +2261,8 @@ static int write_ldt(CPUX86State *env, @@ -2158,7 +2261,8 @@ static int write_ldt(CPUX86State *env,
2158 2261
2159 if (bytecount != sizeof(ldt_info)) 2262 if (bytecount != sizeof(ldt_info))
2160 return -EINVAL; 2263 return -EINVAL;
2161 - lock_user_struct(target_ldt_info, ptr, 1); 2264 + if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
  2265 + return -EFAULT;
2162 ldt_info.entry_number = tswap32(target_ldt_info->entry_number); 2266 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2163 ldt_info.base_addr = tswapl(target_ldt_info->base_addr); 2267 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2164 ldt_info.limit = tswap32(target_ldt_info->limit); 2268 ldt_info.limit = tswap32(target_ldt_info->limit);
@@ -2365,7 +2469,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -2365,7 +2469,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2365 2469
2366 switch(cmd) { 2470 switch(cmd) {
2367 case TARGET_F_GETLK: 2471 case TARGET_F_GETLK:
2368 - lock_user_struct(target_fl, arg, 1); 2472 + if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
  2473 + return -TARGET_EFAULT;
2369 fl.l_type = tswap16(target_fl->l_type); 2474 fl.l_type = tswap16(target_fl->l_type);
2370 fl.l_whence = tswap16(target_fl->l_whence); 2475 fl.l_whence = tswap16(target_fl->l_whence);
2371 fl.l_start = tswapl(target_fl->l_start); 2476 fl.l_start = tswapl(target_fl->l_start);
@@ -2374,7 +2479,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -2374,7 +2479,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2374 unlock_user_struct(target_fl, arg, 0); 2479 unlock_user_struct(target_fl, arg, 0);
2375 ret = fcntl(fd, cmd, &fl); 2480 ret = fcntl(fd, cmd, &fl);
2376 if (ret == 0) { 2481 if (ret == 0) {
2377 - lock_user_struct(target_fl, arg, 0); 2482 + if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
  2483 + return -TARGET_EFAULT;
2378 target_fl->l_type = tswap16(fl.l_type); 2484 target_fl->l_type = tswap16(fl.l_type);
2379 target_fl->l_whence = tswap16(fl.l_whence); 2485 target_fl->l_whence = tswap16(fl.l_whence);
2380 target_fl->l_start = tswapl(fl.l_start); 2486 target_fl->l_start = tswapl(fl.l_start);
@@ -2386,7 +2492,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -2386,7 +2492,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2386 2492
2387 case TARGET_F_SETLK: 2493 case TARGET_F_SETLK:
2388 case TARGET_F_SETLKW: 2494 case TARGET_F_SETLKW:
2389 - lock_user_struct(target_fl, arg, 1); 2495 + if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
  2496 + return -TARGET_EFAULT;
2390 fl.l_type = tswap16(target_fl->l_type); 2497 fl.l_type = tswap16(target_fl->l_type);
2391 fl.l_whence = tswap16(target_fl->l_whence); 2498 fl.l_whence = tswap16(target_fl->l_whence);
2392 fl.l_start = tswapl(target_fl->l_start); 2499 fl.l_start = tswapl(target_fl->l_start);
@@ -2397,7 +2504,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -2397,7 +2504,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2397 break; 2504 break;
2398 2505
2399 case TARGET_F_GETLK64: 2506 case TARGET_F_GETLK64:
2400 - lock_user_struct(target_fl64, arg, 1); 2507 + if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
  2508 + return -TARGET_EFAULT;
2401 fl64.l_type = tswap16(target_fl64->l_type) >> 1; 2509 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2402 fl64.l_whence = tswap16(target_fl64->l_whence); 2510 fl64.l_whence = tswap16(target_fl64->l_whence);
2403 fl64.l_start = tswapl(target_fl64->l_start); 2511 fl64.l_start = tswapl(target_fl64->l_start);
@@ -2406,7 +2514,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -2406,7 +2514,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2406 unlock_user_struct(target_fl64, arg, 0); 2514 unlock_user_struct(target_fl64, arg, 0);
2407 ret = fcntl(fd, cmd >> 1, &fl64); 2515 ret = fcntl(fd, cmd >> 1, &fl64);
2408 if (ret == 0) { 2516 if (ret == 0) {
2409 - lock_user_struct(target_fl64, arg, 0); 2517 + if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
  2518 + return -TARGET_EFAULT;
2410 target_fl64->l_type = tswap16(fl64.l_type) >> 1; 2519 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2411 target_fl64->l_whence = tswap16(fl64.l_whence); 2520 target_fl64->l_whence = tswap16(fl64.l_whence);
2412 target_fl64->l_start = tswapl(fl64.l_start); 2521 target_fl64->l_start = tswapl(fl64.l_start);
@@ -2417,14 +2526,15 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -2417,14 +2526,15 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2417 break; 2526 break;
2418 case TARGET_F_SETLK64: 2527 case TARGET_F_SETLK64:
2419 case TARGET_F_SETLKW64: 2528 case TARGET_F_SETLKW64:
2420 - lock_user_struct(target_fl64, arg, 1); 2529 + if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
  2530 + return -TARGET_EFAULT;
2421 fl64.l_type = tswap16(target_fl64->l_type) >> 1; 2531 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2422 fl64.l_whence = tswap16(target_fl64->l_whence); 2532 fl64.l_whence = tswap16(target_fl64->l_whence);
2423 fl64.l_start = tswapl(target_fl64->l_start); 2533 fl64.l_start = tswapl(target_fl64->l_start);
2424 fl64.l_len = tswapl(target_fl64->l_len); 2534 fl64.l_len = tswapl(target_fl64->l_len);
2425 fl64.l_pid = tswap16(target_fl64->l_pid); 2535 fl64.l_pid = tswap16(target_fl64->l_pid);
2426 unlock_user_struct(target_fl64, arg, 0); 2536 unlock_user_struct(target_fl64, arg, 0);
2427 - ret = fcntl(fd, cmd >> 1, &fl64); 2537 + ret = fcntl(fd, cmd >> 1, &fl64);
2428 break; 2538 break;
2429 2539
2430 case F_GETFL: 2540 case F_GETFL:
@@ -2577,23 +2687,25 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1, @@ -2577,23 +2687,25 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
2577 } 2687 }
2578 #endif 2688 #endif
2579 2689
2580 -static inline void target_to_host_timespec(struct timespec *host_ts,  
2581 - abi_ulong target_addr) 2690 +static inline abi_long target_to_host_timespec(struct timespec *host_ts,
  2691 + abi_ulong target_addr)
2582 { 2692 {
2583 struct target_timespec *target_ts; 2693 struct target_timespec *target_ts;
2584 2694
2585 - lock_user_struct(target_ts, target_addr, 1); 2695 + if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
  2696 + return -TARGET_EFAULT;
2586 host_ts->tv_sec = tswapl(target_ts->tv_sec); 2697 host_ts->tv_sec = tswapl(target_ts->tv_sec);
2587 host_ts->tv_nsec = tswapl(target_ts->tv_nsec); 2698 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
2588 unlock_user_struct(target_ts, target_addr, 0); 2699 unlock_user_struct(target_ts, target_addr, 0);
2589 } 2700 }
2590 2701
2591 -static inline void host_to_target_timespec(abi_ulong target_addr,  
2592 - struct timespec *host_ts) 2702 +static inline abi_long host_to_target_timespec(abi_ulong target_addr,
  2703 + struct timespec *host_ts)
2593 { 2704 {
2594 struct target_timespec *target_ts; 2705 struct target_timespec *target_ts;
2595 2706
2596 - lock_user_struct(target_ts, target_addr, 0); 2707 + if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
  2708 + return -TARGET_EFAULT;
2597 target_ts->tv_sec = tswapl(host_ts->tv_sec); 2709 target_ts->tv_sec = tswapl(host_ts->tv_sec);
2598 target_ts->tv_nsec = tswapl(host_ts->tv_nsec); 2710 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
2599 unlock_user_struct(target_ts, target_addr, 1); 2711 unlock_user_struct(target_ts, target_addr, 1);
@@ -2629,17 +2741,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2629,17 +2741,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2629 break; 2741 break;
2630 case TARGET_NR_read: 2742 case TARGET_NR_read:
2631 page_unprotect_range(arg2, arg3); 2743 page_unprotect_range(arg2, arg3);
2632 - p = lock_user(arg2, arg3, 0); 2744 + if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
  2745 + goto efault;
2633 ret = get_errno(read(arg1, p, arg3)); 2746 ret = get_errno(read(arg1, p, arg3));
2634 unlock_user(p, arg2, ret); 2747 unlock_user(p, arg2, ret);
2635 break; 2748 break;
2636 case TARGET_NR_write: 2749 case TARGET_NR_write:
2637 - p = lock_user(arg2, arg3, 1); 2750 + if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
  2751 + goto efault;
2638 ret = get_errno(write(arg1, p, arg3)); 2752 ret = get_errno(write(arg1, p, arg3));
2639 unlock_user(p, arg2, 0); 2753 unlock_user(p, arg2, 0);
2640 break; 2754 break;
2641 case TARGET_NR_open: 2755 case TARGET_NR_open:
2642 - p = lock_user_string(arg1); 2756 + if (!(p = lock_user_string(arg1))) {
  2757 + return -TARGET_EFAULT;
  2758 + goto fail;
  2759 + }
2643 ret = get_errno(open(path(p), 2760 ret = get_errno(open(path(p),
2644 target_to_host_bitmask(arg2, fcntl_flags_tbl), 2761 target_to_host_bitmask(arg2, fcntl_flags_tbl),
2645 arg3)); 2762 arg3));
@@ -2647,21 +2764,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2647,21 +2764,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2647 break; 2764 break;
2648 #if defined(TARGET_NR_openat) && defined(__NR_openat) 2765 #if defined(TARGET_NR_openat) && defined(__NR_openat)
2649 case TARGET_NR_openat: 2766 case TARGET_NR_openat:
2650 - if (!arg2) {  
2651 - ret = -TARGET_EFAULT;  
2652 - goto fail;  
2653 - }  
2654 - p = lock_user_string(arg2);  
2655 - if (!access_ok(VERIFY_READ, p, 1))  
2656 - /* Don't "goto fail" so that cleanup can happen. */  
2657 - ret = -TARGET_EFAULT;  
2658 - else  
2659 - ret = get_errno(sys_openat(arg1,  
2660 - path(p),  
2661 - target_to_host_bitmask(arg3, fcntl_flags_tbl),  
2662 - arg4));  
2663 - if (p)  
2664 - unlock_user(p, arg2, 0); 2767 + if (!(p = lock_user_string(arg2)))
  2768 + goto efault;
  2769 + ret = get_errno(sys_openat(arg1,
  2770 + path(p),
  2771 + target_to_host_bitmask(arg3, fcntl_flags_tbl),
  2772 + arg4));
  2773 + unlock_user(p, arg2, 0);
2665 break; 2774 break;
2666 #endif 2775 #endif
2667 case TARGET_NR_close: 2776 case TARGET_NR_close:
@@ -2685,7 +2794,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2685,7 +2794,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2685 #endif 2794 #endif
2686 #ifdef TARGET_NR_creat /* not on alpha */ 2795 #ifdef TARGET_NR_creat /* not on alpha */
2687 case TARGET_NR_creat: 2796 case TARGET_NR_creat:
2688 - p = lock_user_string(arg1); 2797 + if (!(p = lock_user_string(arg1)))
  2798 + goto efault;
2689 ret = get_errno(creat(p, arg2)); 2799 ret = get_errno(creat(p, arg2));
2690 unlock_user(p, arg1, 0); 2800 unlock_user(p, arg1, 0);
2691 break; 2801 break;
@@ -2695,54 +2805,43 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2695,54 +2805,43 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2695 void * p2; 2805 void * p2;
2696 p = lock_user_string(arg1); 2806 p = lock_user_string(arg1);
2697 p2 = lock_user_string(arg2); 2807 p2 = lock_user_string(arg2);
2698 - ret = get_errno(link(p, p2)); 2808 + if (!p || !p2)
  2809 + ret = -TARGET_EFAULT;
  2810 + else
  2811 + ret = get_errno(link(p, p2));
2699 unlock_user(p2, arg2, 0); 2812 unlock_user(p2, arg2, 0);
2700 unlock_user(p, arg1, 0); 2813 unlock_user(p, arg1, 0);
2701 } 2814 }
2702 break; 2815 break;
2703 #if defined(TARGET_NR_linkat) && defined(__NR_linkat) 2816 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
2704 case TARGET_NR_linkat: 2817 case TARGET_NR_linkat:
2705 - if (!arg2 || !arg4) {  
2706 - ret = -TARGET_EFAULT;  
2707 - goto fail;  
2708 - }  
2709 { 2818 {
2710 void * p2 = NULL; 2819 void * p2 = NULL;
  2820 + if (!arg2 || !arg4)
  2821 + goto efault;
2711 p = lock_user_string(arg2); 2822 p = lock_user_string(arg2);
2712 p2 = lock_user_string(arg4); 2823 p2 = lock_user_string(arg4);
2713 - if (!access_ok(VERIFY_READ, p, 1)  
2714 - || !access_ok(VERIFY_READ, p2, 1))  
2715 - /* Don't "goto fail" so that cleanup can happen. */ 2824 + if (!p || !p2)
2716 ret = -TARGET_EFAULT; 2825 ret = -TARGET_EFAULT;
2717 else 2826 else
2718 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5)); 2827 ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
2719 - if (p2)  
2720 - unlock_user(p, arg2, 0);  
2721 - if (p)  
2722 - unlock_user(p2, arg4, 0); 2828 + unlock_user(p, arg2, 0);
  2829 + unlock_user(p2, arg4, 0);
2723 } 2830 }
2724 break; 2831 break;
2725 #endif 2832 #endif
2726 case TARGET_NR_unlink: 2833 case TARGET_NR_unlink:
2727 - p = lock_user_string(arg1); 2834 + if (!(p = lock_user_string(arg1)))
  2835 + goto efault;
2728 ret = get_errno(unlink(p)); 2836 ret = get_errno(unlink(p));
2729 unlock_user(p, arg1, 0); 2837 unlock_user(p, arg1, 0);
2730 break; 2838 break;
2731 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat) 2839 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
2732 case TARGET_NR_unlinkat: 2840 case TARGET_NR_unlinkat:
2733 - if (!arg2) {  
2734 - ret = -TARGET_EFAULT;  
2735 - goto fail;  
2736 - }  
2737 - p = lock_user_string(arg2);  
2738 - if (!access_ok(VERIFY_READ, p, 1))  
2739 - /* Don't "goto fail" so that cleanup can happen. */  
2740 - ret = -TARGET_EFAULT;  
2741 - else  
2742 - ret = get_errno(sys_unlinkat(arg1, p, arg3));  
2743 - if (p)  
2744 - unlock_user(p, arg2, 0);  
2745 - break; 2841 + if (!(p = lock_user_string(arg2)))
  2842 + goto efault;
  2843 + ret = get_errno(sys_unlinkat(arg1, p, arg3));
  2844 + unlock_user(p, arg2, 0);
2746 #endif 2845 #endif
2747 case TARGET_NR_execve: 2846 case TARGET_NR_execve:
2748 { 2847 {
@@ -2771,7 +2870,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2771,7 +2870,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2771 addr = tgetl(gp); 2870 addr = tgetl(gp);
2772 if (!addr) 2871 if (!addr)
2773 break; 2872 break;
2774 - *q = lock_user_string(addr); 2873 + if (!(*q = lock_user_string(addr))) {
  2874 + ret = -TARGET_EFAULT;
  2875 + goto execve_fail;
  2876 + }
2775 } 2877 }
2776 *q = NULL; 2878 *q = NULL;
2777 2879
@@ -2780,14 +2882,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2780,14 +2882,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2780 addr = tgetl(gp); 2882 addr = tgetl(gp);
2781 if (!addr) 2883 if (!addr)
2782 break; 2884 break;
2783 - *q = lock_user_string(addr); 2885 + if (!(*q = lock_user_string(addr))) {
  2886 + ret = -TARGET_EFAULT;
  2887 + goto execve_fail;
  2888 + }
2784 } 2889 }
2785 *q = NULL; 2890 *q = NULL;
2786 2891
2787 - p = lock_user_string(arg1); 2892 + if (!(p = lock_user_string(arg1))) {
  2893 + ret = -TARGET_EFAULT;
  2894 + goto execve_fail;
  2895 + }
2788 ret = get_errno(execve(p, argp, envp)); 2896 ret = get_errno(execve(p, argp, envp));
2789 unlock_user(p, arg1, 0); 2897 unlock_user(p, arg1, 0);
2790 2898
  2899 + execve_fail:
2791 for (gp = guest_argp, q = argp; *q; 2900 for (gp = guest_argp, q = argp; *q;
2792 gp += sizeof(abi_ulong), q++) { 2901 gp += sizeof(abi_ulong), q++) {
2793 addr = tgetl(gp); 2902 addr = tgetl(gp);
@@ -2801,7 +2910,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2801,7 +2910,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2801 } 2910 }
2802 break; 2911 break;
2803 case TARGET_NR_chdir: 2912 case TARGET_NR_chdir:
2804 - p = lock_user_string(arg1); 2913 + if (!(p = lock_user_string(arg1)))
  2914 + goto efault;
2805 ret = get_errno(chdir(p)); 2915 ret = get_errno(chdir(p));
2806 unlock_user(p, arg1, 0); 2916 unlock_user(p, arg1, 0);
2807 break; 2917 break;
@@ -2816,28 +2926,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2816,28 +2926,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2816 break; 2926 break;
2817 #endif 2927 #endif
2818 case TARGET_NR_mknod: 2928 case TARGET_NR_mknod:
2819 - p = lock_user_string(arg1); 2929 + if (!(p = lock_user_string(arg1)))
  2930 + goto efault;
2820 ret = get_errno(mknod(p, arg2, arg3)); 2931 ret = get_errno(mknod(p, arg2, arg3));
2821 unlock_user(p, arg1, 0); 2932 unlock_user(p, arg1, 0);
2822 break; 2933 break;
2823 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat) 2934 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
2824 case TARGET_NR_mknodat: 2935 case TARGET_NR_mknodat:
2825 - if (!arg2) {  
2826 - ret = -TARGET_EFAULT;  
2827 - goto fail;  
2828 - }  
2829 - p = lock_user_string(arg2);  
2830 - if (!access_ok(VERIFY_READ, p, 1))  
2831 - /* Don't "goto fail" so that cleanup can happen. */  
2832 - ret = -TARGET_EFAULT;  
2833 - else  
2834 - ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));  
2835 - if (p)  
2836 - unlock_user(p, arg2, 0); 2936 + if (!(p = lock_user_string(arg2)))
  2937 + goto efault;
  2938 + ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
  2939 + unlock_user(p, arg2, 0);
2837 break; 2940 break;
2838 #endif 2941 #endif
2839 case TARGET_NR_chmod: 2942 case TARGET_NR_chmod:
2840 - p = lock_user_string(arg1); 2943 + if (!(p = lock_user_string(arg1)))
  2944 + goto efault;
2841 ret = get_errno(chmod(p, arg2)); 2945 ret = get_errno(chmod(p, arg2));
2842 unlock_user(p, arg1, 0); 2946 unlock_user(p, arg1, 0);
2843 break; 2947 break;
@@ -2866,15 +2970,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2866,15 +2970,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2866 p = lock_user_string(arg1); 2970 p = lock_user_string(arg1);
2867 p2 = lock_user_string(arg2); 2971 p2 = lock_user_string(arg2);
2868 p3 = lock_user_string(arg3); 2972 p3 = lock_user_string(arg3);
2869 - ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, (const void *)arg5));  
2870 - unlock_user(p, arg1, 0);  
2871 - unlock_user(p2, arg2, 0);  
2872 - unlock_user(p3, arg3, 0); 2973 + if (!p || !p2 || !p3)
  2974 + ret = -TARGET_EFAULT;
  2975 + else
  2976 + /* FIXME - arg5 should be locked, but it isn't clear how to
  2977 + * do that since it's not guaranteed to be a NULL-terminated
  2978 + * string.
  2979 + */
  2980 + ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
  2981 + unlock_user(p, arg1, 0);
  2982 + unlock_user(p2, arg2, 0);
  2983 + unlock_user(p3, arg3, 0);
2873 break; 2984 break;
2874 } 2985 }
2875 #ifdef TARGET_NR_umount 2986 #ifdef TARGET_NR_umount
2876 case TARGET_NR_umount: 2987 case TARGET_NR_umount:
2877 - p = lock_user_string(arg1); 2988 + if (!(p = lock_user_string(arg1)))
  2989 + goto efault;
2878 ret = get_errno(umount(p)); 2990 ret = get_errno(umount(p));
2879 unlock_user(p, arg1, 0); 2991 unlock_user(p, arg1, 0);
2880 break; 2992 break;
@@ -2910,7 +3022,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2910,7 +3022,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2910 struct utimbuf tbuf, *host_tbuf; 3022 struct utimbuf tbuf, *host_tbuf;
2911 struct target_utimbuf *target_tbuf; 3023 struct target_utimbuf *target_tbuf;
2912 if (arg2) { 3024 if (arg2) {
2913 - lock_user_struct(target_tbuf, arg2, 1); 3025 + if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
  3026 + goto efault;
2914 tbuf.actime = tswapl(target_tbuf->actime); 3027 tbuf.actime = tswapl(target_tbuf->actime);
2915 tbuf.modtime = tswapl(target_tbuf->modtime); 3028 tbuf.modtime = tswapl(target_tbuf->modtime);
2916 unlock_user_struct(target_tbuf, arg2, 0); 3029 unlock_user_struct(target_tbuf, arg2, 0);
@@ -2918,7 +3031,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2918,7 +3031,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2918 } else { 3031 } else {
2919 host_tbuf = NULL; 3032 host_tbuf = NULL;
2920 } 3033 }
2921 - p = lock_user_string(arg1); 3034 + if (!(p = lock_user_string(arg1)))
  3035 + goto efault;
2922 ret = get_errno(utime(p, host_tbuf)); 3036 ret = get_errno(utime(p, host_tbuf));
2923 unlock_user(p, arg1, 0); 3037 unlock_user(p, arg1, 0);
2924 } 3038 }
@@ -2935,7 +3049,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2935,7 +3049,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2935 } else { 3049 } else {
2936 tvp = NULL; 3050 tvp = NULL;
2937 } 3051 }
2938 - p = lock_user_string(arg1); 3052 + if (!(p = lock_user_string(arg1)))
  3053 + goto efault;
2939 ret = get_errno(utimes(p, tvp)); 3054 ret = get_errno(utimes(p, tvp));
2940 unlock_user(p, arg1, 0); 3055 unlock_user(p, arg1, 0);
2941 } 3056 }
@@ -2949,24 +3064,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2949,24 +3064,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2949 goto unimplemented; 3064 goto unimplemented;
2950 #endif 3065 #endif
2951 case TARGET_NR_access: 3066 case TARGET_NR_access:
2952 - p = lock_user_string(arg1); 3067 + if (!(p = lock_user_string(arg1)))
  3068 + goto efault;
2953 ret = get_errno(access(p, arg2)); 3069 ret = get_errno(access(p, arg2));
2954 unlock_user(p, arg1, 0); 3070 unlock_user(p, arg1, 0);
2955 break; 3071 break;
2956 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) 3072 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
2957 case TARGET_NR_faccessat: 3073 case TARGET_NR_faccessat:
2958 - if (!arg2) {  
2959 - ret = -TARGET_EFAULT;  
2960 - goto fail;  
2961 - }  
2962 - p = lock_user_string(arg2);  
2963 - if (!access_ok(VERIFY_READ, p, 1))  
2964 - /* Don't "goto fail" so that cleanup can happen. */  
2965 - ret = -TARGET_EFAULT;  
2966 - else  
2967 - ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));  
2968 - if (p)  
2969 - unlock_user(p, arg2, 0); 3074 + if (!(p = lock_user_string(arg2)))
  3075 + goto efault;
  3076 + ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
  3077 + unlock_user(p, arg2, 0);
2970 break; 3078 break;
2971 #endif 3079 #endif
2972 #ifdef TARGET_NR_nice /* not on alpha */ 3080 #ifdef TARGET_NR_nice /* not on alpha */
@@ -2990,57 +3098,46 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -2990,57 +3098,46 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2990 void *p2; 3098 void *p2;
2991 p = lock_user_string(arg1); 3099 p = lock_user_string(arg1);
2992 p2 = lock_user_string(arg2); 3100 p2 = lock_user_string(arg2);
2993 - ret = get_errno(rename(p, p2)); 3101 + if (!p || !p2)
  3102 + ret = -TARGET_EFAULT;
  3103 + else
  3104 + ret = get_errno(rename(p, p2));
2994 unlock_user(p2, arg2, 0); 3105 unlock_user(p2, arg2, 0);
2995 unlock_user(p, arg1, 0); 3106 unlock_user(p, arg1, 0);
2996 } 3107 }
2997 break; 3108 break;
2998 #if defined(TARGET_NR_renameat) && defined(__NR_renameat) 3109 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
2999 case TARGET_NR_renameat: 3110 case TARGET_NR_renameat:
3000 - if (!arg2 || !arg4) {  
3001 - ret = -TARGET_EFAULT;  
3002 - goto fail;  
3003 - }  
3004 { 3111 {
3005 - void *p2 = NULL; 3112 + void *p2;
3006 p = lock_user_string(arg2); 3113 p = lock_user_string(arg2);
3007 p2 = lock_user_string(arg4); 3114 p2 = lock_user_string(arg4);
3008 - if (!access_ok(VERIFY_READ, p, 1)  
3009 - || !access_ok(VERIFY_READ, p2, 1))  
3010 - /* Don't "goto fail" so that cleanup can happen. */ 3115 + if (!p || !p2)
3011 ret = -TARGET_EFAULT; 3116 ret = -TARGET_EFAULT;
3012 else 3117 else
3013 ret = get_errno(sys_renameat(arg1, p, arg3, p2)); 3118 ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3014 - if (p2)  
3015 - unlock_user(p2, arg4, 0);  
3016 - if (p)  
3017 - unlock_user(p, arg2, 0); 3119 + unlock_user(p2, arg4, 0);
  3120 + unlock_user(p, arg2, 0);
3018 } 3121 }
3019 break; 3122 break;
3020 #endif 3123 #endif
3021 case TARGET_NR_mkdir: 3124 case TARGET_NR_mkdir:
3022 - p = lock_user_string(arg1); 3125 + if (!(p = lock_user_string(arg1)))
  3126 + goto efault;
3023 ret = get_errno(mkdir(p, arg2)); 3127 ret = get_errno(mkdir(p, arg2));
3024 unlock_user(p, arg1, 0); 3128 unlock_user(p, arg1, 0);
3025 break; 3129 break;
3026 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat) 3130 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3027 case TARGET_NR_mkdirat: 3131 case TARGET_NR_mkdirat:
3028 - if (!arg2) {  
3029 - ret = -TARGET_EFAULT;  
3030 - goto fail;  
3031 - }  
3032 - p = lock_user_string(arg2);  
3033 - if (!access_ok(VERIFY_READ, p, 1))  
3034 - /* Don't "goto fail" so that cleanup can happen. */  
3035 - ret = -TARGET_EFAULT;  
3036 - else  
3037 - ret = get_errno(sys_mkdirat(arg1, p, arg3));  
3038 - if (p)  
3039 - unlock_user(p, arg2, 0); 3132 + if (!(p = lock_user_string(arg2)))
  3133 + goto efault;
  3134 + ret = get_errno(sys_mkdirat(arg1, p, arg3));
  3135 + unlock_user(p, arg2, 0);
3040 break; 3136 break;
3041 #endif 3137 #endif
3042 case TARGET_NR_rmdir: 3138 case TARGET_NR_rmdir:
3043 - p = lock_user_string(arg1); 3139 + if (!(p = lock_user_string(arg1)))
  3140 + goto efault;
3044 ret = get_errno(rmdir(p)); 3141 ret = get_errno(rmdir(p));
3045 unlock_user(p, arg1, 0); 3142 unlock_user(p, arg1, 0);
3046 break; 3143 break;
@@ -3069,7 +3166,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3069,7 +3166,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3069 struct tms tms; 3166 struct tms tms;
3070 ret = get_errno(times(&tms)); 3167 ret = get_errno(times(&tms));
3071 if (arg1) { 3168 if (arg1) {
3072 - tmsp = lock_user(arg1, sizeof(struct target_tms), 0); 3169 + tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
  3170 + if (!tmsp)
  3171 + goto efault;
3073 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime)); 3172 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3074 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime)); 3173 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3075 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime)); 3174 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
@@ -3088,13 +3187,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3088,13 +3187,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3088 goto unimplemented; 3187 goto unimplemented;
3089 #endif 3188 #endif
3090 case TARGET_NR_acct: 3189 case TARGET_NR_acct:
3091 - p = lock_user_string(arg1); 3190 + if (!(p = lock_user_string(arg1)))
  3191 + goto efault;
3092 ret = get_errno(acct(path(p))); 3192 ret = get_errno(acct(path(p)));
3093 unlock_user(p, arg1, 0); 3193 unlock_user(p, arg1, 0);
3094 break; 3194 break;
3095 #ifdef TARGET_NR_umount2 /* not on alpha */ 3195 #ifdef TARGET_NR_umount2 /* not on alpha */
3096 case TARGET_NR_umount2: 3196 case TARGET_NR_umount2:
3097 - p = lock_user_string(arg1); 3197 + if (!(p = lock_user_string(arg1)))
  3198 + goto efault;
3098 ret = get_errno(umount2(p, arg2)); 3199 ret = get_errno(umount2(p, arg2));
3099 unlock_user(p, arg1, 0); 3200 unlock_user(p, arg1, 0);
3100 break; 3201 break;
@@ -3128,7 +3229,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3128,7 +3229,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3128 ret = get_errno(umask(arg1)); 3229 ret = get_errno(umask(arg1));
3129 break; 3230 break;
3130 case TARGET_NR_chroot: 3231 case TARGET_NR_chroot:
3131 - p = lock_user_string(arg1); 3232 + if (!(p = lock_user_string(arg1)))
  3233 + goto efault;
3132 ret = get_errno(chroot(p)); 3234 ret = get_errno(chroot(p));
3133 unlock_user(p, arg1, 0); 3235 unlock_user(p, arg1, 0);
3134 break; 3236 break;
@@ -3155,7 +3257,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3155,7 +3257,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3155 struct target_old_sigaction *old_act; 3257 struct target_old_sigaction *old_act;
3156 struct target_sigaction act, oact, *pact; 3258 struct target_sigaction act, oact, *pact;
3157 if (arg2) { 3259 if (arg2) {
3158 - lock_user_struct(old_act, arg2, 1); 3260 + if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
  3261 + goto efault;
3159 act._sa_handler = old_act->_sa_handler; 3262 act._sa_handler = old_act->_sa_handler;
3160 target_siginitset(&act.sa_mask, old_act->sa_mask); 3263 target_siginitset(&act.sa_mask, old_act->sa_mask);
3161 act.sa_flags = old_act->sa_flags; 3264 act.sa_flags = old_act->sa_flags;
@@ -3167,7 +3270,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3167,7 +3270,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3167 } 3270 }
3168 ret = get_errno(do_sigaction(arg1, pact, &oact)); 3271 ret = get_errno(do_sigaction(arg1, pact, &oact));
3169 if (!is_error(ret) && arg3) { 3272 if (!is_error(ret) && arg3) {
3170 - lock_user_struct(old_act, arg3, 0); 3273 + if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
  3274 + goto efault;
3171 old_act->_sa_handler = oact._sa_handler; 3275 old_act->_sa_handler = oact._sa_handler;
3172 old_act->sa_mask = oact.sa_mask.sig[0]; 3276 old_act->sa_mask = oact.sa_mask.sig[0];
3173 old_act->sa_flags = oact.sa_flags; 3277 old_act->sa_flags = oact.sa_flags;
@@ -3178,7 +3282,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3178,7 +3282,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3178 struct target_sigaction act, oact, *pact, *old_act; 3282 struct target_sigaction act, oact, *pact, *old_act;
3179 3283
3180 if (arg2) { 3284 if (arg2) {
3181 - lock_user_struct(old_act, arg2, 1); 3285 + if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
  3286 + goto efault;
3182 act._sa_handler = old_act->_sa_handler; 3287 act._sa_handler = old_act->_sa_handler;
3183 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]); 3288 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3184 act.sa_flags = old_act->sa_flags; 3289 act.sa_flags = old_act->sa_flags;
@@ -3191,7 +3296,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3191,7 +3296,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3191 ret = get_errno(do_sigaction(arg1, pact, &oact)); 3296 ret = get_errno(do_sigaction(arg1, pact, &oact));
3192 3297
3193 if (!is_error(ret) && arg3) { 3298 if (!is_error(ret) && arg3) {
3194 - lock_user_struct(old_act, arg3, 0); 3299 + if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
  3300 + goto efault;
3195 old_act->_sa_handler = oact._sa_handler; 3301 old_act->_sa_handler = oact._sa_handler;
3196 old_act->sa_flags = oact.sa_flags; 3302 old_act->sa_flags = oact.sa_flags;
3197 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0]; 3303 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
@@ -3209,18 +3315,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3209,18 +3315,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3209 struct target_sigaction *act; 3315 struct target_sigaction *act;
3210 struct target_sigaction *oact; 3316 struct target_sigaction *oact;
3211 3317
3212 - if (arg2)  
3213 - lock_user_struct(act, arg2, 1);  
3214 - else 3318 + if (arg2) {
  3319 + if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
  3320 + goto efault;
  3321 + } else
3215 act = NULL; 3322 act = NULL;
3216 - if (arg3)  
3217 - lock_user_struct(oact, arg3, 0);  
3218 - else 3323 + if (arg3) {
  3324 + if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
  3325 + ret = -TARGET_EFAULT;
  3326 + goto rt_sigaction_fail;
  3327 + }
  3328 + } else
3219 oact = NULL; 3329 oact = NULL;
3220 ret = get_errno(do_sigaction(arg1, act, oact)); 3330 ret = get_errno(do_sigaction(arg1, act, oact));
3221 - if (arg2) 3331 + rt_sigaction_fail:
  3332 + if (act)
3222 unlock_user_struct(act, arg2, 0); 3333 unlock_user_struct(act, arg2, 0);
3223 - if (arg3) 3334 + if (oact)
3224 unlock_user_struct(oact, arg3, 1); 3335 unlock_user_struct(oact, arg3, 1);
3225 } 3336 }
3226 break; 3337 break;
@@ -3270,7 +3381,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3270,7 +3381,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3270 ret = -TARGET_EINVAL; 3381 ret = -TARGET_EINVAL;
3271 goto fail; 3382 goto fail;
3272 } 3383 }
3273 - p = lock_user(arg2, sizeof(target_sigset_t), 1); 3384 + if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
  3385 + goto efault;
3274 target_to_host_old_sigset(&set, p); 3386 target_to_host_old_sigset(&set, p);
3275 unlock_user(p, arg2, 0); 3387 unlock_user(p, arg2, 0);
3276 set_ptr = &set; 3388 set_ptr = &set;
@@ -3280,7 +3392,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3280,7 +3392,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3280 } 3392 }
3281 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); 3393 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3282 if (!is_error(ret) && arg3) { 3394 if (!is_error(ret) && arg3) {
3283 - p = lock_user(arg3, sizeof(target_sigset_t), 0); 3395 + if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
  3396 + goto efault;
3284 host_to_target_old_sigset(p, &oldset); 3397 host_to_target_old_sigset(p, &oldset);
3285 unlock_user(p, arg3, sizeof(target_sigset_t)); 3398 unlock_user(p, arg3, sizeof(target_sigset_t));
3286 } 3399 }
@@ -3307,7 +3420,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3307,7 +3420,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3307 ret = -TARGET_EINVAL; 3420 ret = -TARGET_EINVAL;
3308 goto fail; 3421 goto fail;
3309 } 3422 }
3310 - p = lock_user(arg2, sizeof(target_sigset_t), 1); 3423 + if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
  3424 + goto efault;
3311 target_to_host_sigset(&set, p); 3425 target_to_host_sigset(&set, p);
3312 unlock_user(p, arg2, 0); 3426 unlock_user(p, arg2, 0);
3313 set_ptr = &set; 3427 set_ptr = &set;
@@ -3317,7 +3431,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3317,7 +3431,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3317 } 3431 }
3318 ret = get_errno(sigprocmask(how, set_ptr, &oldset)); 3432 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
3319 if (!is_error(ret) && arg3) { 3433 if (!is_error(ret) && arg3) {
3320 - p = lock_user(arg3, sizeof(target_sigset_t), 0); 3434 + if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
  3435 + goto efault;
3321 host_to_target_sigset(p, &oldset); 3436 host_to_target_sigset(p, &oldset);
3322 unlock_user(p, arg3, sizeof(target_sigset_t)); 3437 unlock_user(p, arg3, sizeof(target_sigset_t));
3323 } 3438 }
@@ -3329,7 +3444,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3329,7 +3444,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3329 sigset_t set; 3444 sigset_t set;
3330 ret = get_errno(sigpending(&set)); 3445 ret = get_errno(sigpending(&set));
3331 if (!is_error(ret)) { 3446 if (!is_error(ret)) {
3332 - p = lock_user(arg1, sizeof(target_sigset_t), 0); 3447 + if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
  3448 + goto efault;
3333 host_to_target_old_sigset(p, &set); 3449 host_to_target_old_sigset(p, &set);
3334 unlock_user(p, arg1, sizeof(target_sigset_t)); 3450 unlock_user(p, arg1, sizeof(target_sigset_t));
3335 } 3451 }
@@ -3341,7 +3457,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3341,7 +3457,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3341 sigset_t set; 3457 sigset_t set;
3342 ret = get_errno(sigpending(&set)); 3458 ret = get_errno(sigpending(&set));
3343 if (!is_error(ret)) { 3459 if (!is_error(ret)) {
3344 - p = lock_user(arg1, sizeof(target_sigset_t), 0); 3460 + if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
  3461 + goto efault;
3345 host_to_target_sigset(p, &set); 3462 host_to_target_sigset(p, &set);
3346 unlock_user(p, arg1, sizeof(target_sigset_t)); 3463 unlock_user(p, arg1, sizeof(target_sigset_t));
3347 } 3464 }
@@ -3351,7 +3468,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3351,7 +3468,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3351 case TARGET_NR_sigsuspend: 3468 case TARGET_NR_sigsuspend:
3352 { 3469 {
3353 sigset_t set; 3470 sigset_t set;
3354 - p = lock_user(arg1, sizeof(target_sigset_t), 1); 3471 + if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
  3472 + goto efault;
3355 target_to_host_old_sigset(&set, p); 3473 target_to_host_old_sigset(&set, p);
3356 unlock_user(p, arg1, 0); 3474 unlock_user(p, arg1, 0);
3357 ret = get_errno(sigsuspend(&set)); 3475 ret = get_errno(sigsuspend(&set));
@@ -3361,7 +3479,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3361,7 +3479,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3361 case TARGET_NR_rt_sigsuspend: 3479 case TARGET_NR_rt_sigsuspend:
3362 { 3480 {
3363 sigset_t set; 3481 sigset_t set;
3364 - p = lock_user(arg1, sizeof(target_sigset_t), 1); 3482 + if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
  3483 + goto efault;
3365 target_to_host_sigset(&set, p); 3484 target_to_host_sigset(&set, p);
3366 unlock_user(p, arg1, 0); 3485 unlock_user(p, arg1, 0);
3367 ret = get_errno(sigsuspend(&set)); 3486 ret = get_errno(sigsuspend(&set));
@@ -3373,7 +3492,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3373,7 +3492,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3373 struct timespec uts, *puts; 3492 struct timespec uts, *puts;
3374 siginfo_t uinfo; 3493 siginfo_t uinfo;
3375 3494
3376 - p = lock_user(arg1, sizeof(target_sigset_t), 1); 3495 + if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
  3496 + goto efault;
3377 target_to_host_sigset(&set, p); 3497 target_to_host_sigset(&set, p);
3378 unlock_user(p, arg1, 0); 3498 unlock_user(p, arg1, 0);
3379 if (arg3) { 3499 if (arg3) {
@@ -3384,7 +3504,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3384,7 +3504,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3384 } 3504 }
3385 ret = get_errno(sigtimedwait(&set, &uinfo, puts)); 3505 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
3386 if (!is_error(ret) && arg2) { 3506 if (!is_error(ret) && arg2) {
3387 - p = lock_user(arg2, sizeof(target_sigset_t), 0); 3507 + if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_sigset_t), 0)))
  3508 + goto efault;
3388 host_to_target_siginfo(p, &uinfo); 3509 host_to_target_siginfo(p, &uinfo);
3389 unlock_user(p, arg2, sizeof(target_sigset_t)); 3510 unlock_user(p, arg2, sizeof(target_sigset_t));
3390 } 3511 }
@@ -3393,7 +3514,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3393,7 +3514,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3393 case TARGET_NR_rt_sigqueueinfo: 3514 case TARGET_NR_rt_sigqueueinfo:
3394 { 3515 {
3395 siginfo_t uinfo; 3516 siginfo_t uinfo;
3396 - p = lock_user(arg3, sizeof(target_sigset_t), 1); 3517 + if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
  3518 + goto efault;
3397 target_to_host_siginfo(&uinfo, p); 3519 target_to_host_siginfo(&uinfo, p);
3398 unlock_user(p, arg1, 0); 3520 unlock_user(p, arg1, 0);
3399 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); 3521 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
@@ -3410,7 +3532,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3410,7 +3532,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3410 ret = do_rt_sigreturn(cpu_env); 3532 ret = do_rt_sigreturn(cpu_env);
3411 break; 3533 break;
3412 case TARGET_NR_sethostname: 3534 case TARGET_NR_sethostname:
3413 - p = lock_user_string(arg1); 3535 + if (!(p = lock_user_string(arg1)))
  3536 + goto efault;
3414 ret = get_errno(sethostname(p, arg2)); 3537 ret = get_errno(sethostname(p, arg2));
3415 unlock_user(p, arg1, 0); 3538 unlock_user(p, arg1, 0);
3416 break; 3539 break;
@@ -3420,7 +3543,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3420,7 +3543,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3420 int resource = arg1; 3543 int resource = arg1;
3421 struct target_rlimit *target_rlim; 3544 struct target_rlimit *target_rlim;
3422 struct rlimit rlim; 3545 struct rlimit rlim;
3423 - lock_user_struct(target_rlim, arg2, 1); 3546 + if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
  3547 + goto efault;
3424 rlim.rlim_cur = tswapl(target_rlim->rlim_cur); 3548 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3425 rlim.rlim_max = tswapl(target_rlim->rlim_max); 3549 rlim.rlim_max = tswapl(target_rlim->rlim_max);
3426 unlock_user_struct(target_rlim, arg2, 0); 3550 unlock_user_struct(target_rlim, arg2, 0);
@@ -3436,7 +3560,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3436,7 +3560,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3436 3560
3437 ret = get_errno(getrlimit(resource, &rlim)); 3561 ret = get_errno(getrlimit(resource, &rlim));
3438 if (!is_error(ret)) { 3562 if (!is_error(ret)) {
3439 - lock_user_struct(target_rlim, arg2, 0); 3563 + if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
  3564 + goto efault;
3440 rlim.rlim_cur = tswapl(target_rlim->rlim_cur); 3565 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3441 rlim.rlim_max = tswapl(target_rlim->rlim_max); 3566 rlim.rlim_max = tswapl(target_rlim->rlim_max);
3442 unlock_user_struct(target_rlim, arg2, 1); 3567 unlock_user_struct(target_rlim, arg2, 1);
@@ -3475,7 +3600,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3475,7 +3600,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3475 abi_ulong inp, outp, exp, tvp; 3600 abi_ulong inp, outp, exp, tvp;
3476 long nsel; 3601 long nsel;
3477 3602
3478 - lock_user_struct(sel, arg1, 1); 3603 + if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
  3604 + goto efault;
3479 nsel = tswapl(sel->n); 3605 nsel = tswapl(sel->n);
3480 inp = tswapl(sel->inp); 3606 inp = tswapl(sel->inp);
3481 outp = tswapl(sel->outp); 3607 outp = tswapl(sel->outp);
@@ -3491,31 +3617,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3491,31 +3617,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3491 void *p2; 3617 void *p2;
3492 p = lock_user_string(arg1); 3618 p = lock_user_string(arg1);
3493 p2 = lock_user_string(arg2); 3619 p2 = lock_user_string(arg2);
3494 - ret = get_errno(symlink(p, p2)); 3620 + if (!p || !p2)
  3621 + ret = -TARGET_EFAULT;
  3622 + else
  3623 + ret = get_errno(symlink(p, p2));
3495 unlock_user(p2, arg2, 0); 3624 unlock_user(p2, arg2, 0);
3496 unlock_user(p, arg1, 0); 3625 unlock_user(p, arg1, 0);
3497 } 3626 }
3498 break; 3627 break;
3499 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat) 3628 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
3500 case TARGET_NR_symlinkat: 3629 case TARGET_NR_symlinkat:
3501 - if (!arg1 || !arg3) {  
3502 - ret = -TARGET_EFAULT;  
3503 - goto fail;  
3504 - }  
3505 { 3630 {
3506 - void *p2 = NULL; 3631 + void *p2;
3507 p = lock_user_string(arg1); 3632 p = lock_user_string(arg1);
3508 p2 = lock_user_string(arg3); 3633 p2 = lock_user_string(arg3);
3509 - if (!access_ok(VERIFY_READ, p, 1)  
3510 - || !access_ok(VERIFY_READ, p2, 1))  
3511 - /* Don't "goto fail" so that cleanup can happen. */ 3634 + if (!p || !p2)
3512 ret = -TARGET_EFAULT; 3635 ret = -TARGET_EFAULT;
3513 else 3636 else
3514 ret = get_errno(sys_symlinkat(p, arg2, p2)); 3637 ret = get_errno(sys_symlinkat(p, arg2, p2));
3515 - if (p2)  
3516 - unlock_user(p2, arg3, 0);  
3517 - if (p)  
3518 - unlock_user(p, arg1, 0); 3638 + unlock_user(p2, arg3, 0);
  3639 + unlock_user(p, arg1, 0);
3519 } 3640 }
3520 break; 3641 break;
3521 #endif 3642 #endif
@@ -3527,32 +3648,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3527,32 +3648,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3527 { 3648 {
3528 void *p2; 3649 void *p2;
3529 p = lock_user_string(arg1); 3650 p = lock_user_string(arg1);
3530 - p2 = lock_user(arg2, arg3, 0);  
3531 - ret = get_errno(readlink(path(p), p2, arg3)); 3651 + p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
  3652 + if (!p || !p2)
  3653 + ret = -TARGET_EFAULT;
  3654 + else
  3655 + ret = get_errno(readlink(path(p), p2, arg3));
3532 unlock_user(p2, arg2, ret); 3656 unlock_user(p2, arg2, ret);
3533 unlock_user(p, arg1, 0); 3657 unlock_user(p, arg1, 0);
3534 } 3658 }
3535 break; 3659 break;
3536 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat) 3660 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
3537 case TARGET_NR_readlinkat: 3661 case TARGET_NR_readlinkat:
3538 - if (!arg2 || !arg3) {  
3539 - ret = -TARGET_EFAULT;  
3540 - goto fail;  
3541 - }  
3542 { 3662 {
3543 - void *p2 = NULL; 3663 + void *p2;
3544 p = lock_user_string(arg2); 3664 p = lock_user_string(arg2);
3545 - p2 = lock_user(arg3, arg4, 0);  
3546 - if (!access_ok(VERIFY_READ, p, 1)  
3547 - || !access_ok(VERIFY_READ, p2, 1))  
3548 - /* Don't "goto fail" so that cleanup can happen. */ 3665 + p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
  3666 + if (!p || !p2)
3549 ret = -TARGET_EFAULT; 3667 ret = -TARGET_EFAULT;
3550 else 3668 else
3551 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4)); 3669 ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
3552 - if (p2)  
3553 - unlock_user(p2, arg3, ret);  
3554 - if (p)  
3555 - unlock_user(p, arg2, 0); 3670 + unlock_user(p2, arg3, ret);
  3671 + unlock_user(p, arg2, 0);
3556 } 3672 }
3557 break; 3673 break;
3558 #endif 3674 #endif
@@ -3562,7 +3678,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3562,7 +3678,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3562 #endif 3678 #endif
3563 #ifdef TARGET_NR_swapon 3679 #ifdef TARGET_NR_swapon
3564 case TARGET_NR_swapon: 3680 case TARGET_NR_swapon:
3565 - p = lock_user_string(arg1); 3681 + if (!(p = lock_user_string(arg1)))
  3682 + goto efault;
3566 ret = get_errno(swapon(p, arg2)); 3683 ret = get_errno(swapon(p, arg2));
3567 unlock_user(p, arg1, 0); 3684 unlock_user(p, arg1, 0);
3568 break; 3685 break;
@@ -3579,7 +3696,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3579,7 +3696,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3579 { 3696 {
3580 abi_ulong *v; 3697 abi_ulong *v;
3581 abi_ulong v1, v2, v3, v4, v5, v6; 3698 abi_ulong v1, v2, v3, v4, v5, v6;
3582 - v = lock_user(arg1, 6 * sizeof(abi_ulong), 1); 3699 + if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
  3700 + goto efault;
3583 v1 = tswapl(v[0]); 3701 v1 = tswapl(v[0]);
3584 v2 = tswapl(v[1]); 3702 v2 = tswapl(v[1]);
3585 v3 = tswapl(v[2]); 3703 v3 = tswapl(v[2]);
@@ -3650,7 +3768,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3650,7 +3768,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3650 break; 3768 break;
3651 #endif 3769 #endif
3652 case TARGET_NR_truncate: 3770 case TARGET_NR_truncate:
3653 - p = lock_user_string(arg1); 3771 + if (!(p = lock_user_string(arg1)))
  3772 + goto efault;
3654 ret = get_errno(truncate(p, arg2)); 3773 ret = get_errno(truncate(p, arg2));
3655 unlock_user(p, arg1, 0); 3774 unlock_user(p, arg1, 0);
3656 break; 3775 break;
@@ -3662,18 +3781,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3662,18 +3781,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3662 break; 3781 break;
3663 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) 3782 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
3664 case TARGET_NR_fchmodat: 3783 case TARGET_NR_fchmodat:
3665 - if (!arg2) {  
3666 - ret = -TARGET_EFAULT;  
3667 - goto fail;  
3668 - }  
3669 - p = lock_user_string(arg2);  
3670 - if (!access_ok(VERIFY_READ, p, 1))  
3671 - /* Don't "goto fail" so that cleanup can happen. */  
3672 - ret = -TARGET_EFAULT;  
3673 - else  
3674 - ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));  
3675 - if (p)  
3676 - unlock_user(p, arg2, 0); 3784 + if (!(p = lock_user_string(arg2)))
  3785 + goto efault;
  3786 + ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
  3787 + unlock_user(p, arg2, 0);
3677 break; 3788 break;
3678 #endif 3789 #endif
3679 case TARGET_NR_getpriority: 3790 case TARGET_NR_getpriority:
@@ -3690,25 +3801,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3690,25 +3801,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3690 goto unimplemented; 3801 goto unimplemented;
3691 #endif 3802 #endif
3692 case TARGET_NR_statfs: 3803 case TARGET_NR_statfs:
3693 - p = lock_user_string(arg1); 3804 + if (!(p = lock_user_string(arg1)))
  3805 + goto efault;
3694 ret = get_errno(statfs(path(p), &stfs)); 3806 ret = get_errno(statfs(path(p), &stfs));
3695 unlock_user(p, arg1, 0); 3807 unlock_user(p, arg1, 0);
3696 convert_statfs: 3808 convert_statfs:
3697 if (!is_error(ret)) { 3809 if (!is_error(ret)) {
3698 struct target_statfs *target_stfs; 3810 struct target_statfs *target_stfs;
3699 3811
3700 - lock_user_struct(target_stfs, arg2, 0);  
3701 - /* ??? put_user is probably wrong. */  
3702 - put_user(stfs.f_type, &target_stfs->f_type);  
3703 - put_user(stfs.f_bsize, &target_stfs->f_bsize);  
3704 - put_user(stfs.f_blocks, &target_stfs->f_blocks);  
3705 - put_user(stfs.f_bfree, &target_stfs->f_bfree);  
3706 - put_user(stfs.f_bavail, &target_stfs->f_bavail);  
3707 - put_user(stfs.f_files, &target_stfs->f_files);  
3708 - put_user(stfs.f_ffree, &target_stfs->f_ffree);  
3709 - put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);  
3710 - put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);  
3711 - put_user(stfs.f_namelen, &target_stfs->f_namelen); 3812 + if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
  3813 + goto efault;
  3814 + __put_user(stfs.f_type, &target_stfs->f_type);
  3815 + __put_user(stfs.f_bsize, &target_stfs->f_bsize);
  3816 + __put_user(stfs.f_blocks, &target_stfs->f_blocks);
  3817 + __put_user(stfs.f_bfree, &target_stfs->f_bfree);
  3818 + __put_user(stfs.f_bavail, &target_stfs->f_bavail);
  3819 + __put_user(stfs.f_files, &target_stfs->f_files);
  3820 + __put_user(stfs.f_ffree, &target_stfs->f_ffree);
  3821 + __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
  3822 + __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
  3823 + __put_user(stfs.f_namelen, &target_stfs->f_namelen);
3712 unlock_user_struct(target_stfs, arg2, 1); 3824 unlock_user_struct(target_stfs, arg2, 1);
3713 } 3825 }
3714 break; 3826 break;
@@ -3717,26 +3829,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3717,26 +3829,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3717 goto convert_statfs; 3829 goto convert_statfs;
3718 #ifdef TARGET_NR_statfs64 3830 #ifdef TARGET_NR_statfs64
3719 case TARGET_NR_statfs64: 3831 case TARGET_NR_statfs64:
3720 - p = lock_user_string(arg1); 3832 + if (!(p = lock_user_string(arg1)))
  3833 + goto efault;
3721 ret = get_errno(statfs(path(p), &stfs)); 3834 ret = get_errno(statfs(path(p), &stfs));
3722 unlock_user(p, arg1, 0); 3835 unlock_user(p, arg1, 0);
3723 convert_statfs64: 3836 convert_statfs64:
3724 if (!is_error(ret)) { 3837 if (!is_error(ret)) {
3725 struct target_statfs64 *target_stfs; 3838 struct target_statfs64 *target_stfs;
3726 3839
3727 - lock_user_struct(target_stfs, arg3, 0);  
3728 - /* ??? put_user is probably wrong. */  
3729 - put_user(stfs.f_type, &target_stfs->f_type);  
3730 - put_user(stfs.f_bsize, &target_stfs->f_bsize);  
3731 - put_user(stfs.f_blocks, &target_stfs->f_blocks);  
3732 - put_user(stfs.f_bfree, &target_stfs->f_bfree);  
3733 - put_user(stfs.f_bavail, &target_stfs->f_bavail);  
3734 - put_user(stfs.f_files, &target_stfs->f_files);  
3735 - put_user(stfs.f_ffree, &target_stfs->f_ffree);  
3736 - put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);  
3737 - put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);  
3738 - put_user(stfs.f_namelen, &target_stfs->f_namelen);  
3739 - unlock_user_struct(target_stfs, arg3, 0); 3840 + if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
  3841 + goto efault;
  3842 + __put_user(stfs.f_type, &target_stfs->f_type);
  3843 + __put_user(stfs.f_bsize, &target_stfs->f_bsize);
  3844 + __put_user(stfs.f_blocks, &target_stfs->f_blocks);
  3845 + __put_user(stfs.f_bfree, &target_stfs->f_bfree);
  3846 + __put_user(stfs.f_bavail, &target_stfs->f_bavail);
  3847 + __put_user(stfs.f_files, &target_stfs->f_files);
  3848 + __put_user(stfs.f_ffree, &target_stfs->f_ffree);
  3849 + __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
  3850 + __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
  3851 + __put_user(stfs.f_namelen, &target_stfs->f_namelen);
  3852 + unlock_user_struct(target_stfs, arg3, 1);
3740 } 3853 }
3741 break; 3854 break;
3742 case TARGET_NR_fstatfs64: 3855 case TARGET_NR_fstatfs64:
@@ -3839,7 +3952,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3839,7 +3952,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3839 #endif 3952 #endif
3840 3953
3841 case TARGET_NR_syslog: 3954 case TARGET_NR_syslog:
3842 - p = lock_user_string(arg2); 3955 + if (!(p = lock_user_string(arg2)))
  3956 + goto efault;
3843 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3)); 3957 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
3844 unlock_user(p, arg2, 0); 3958 unlock_user(p, arg2, 0);
3845 break; 3959 break;
@@ -3880,12 +3994,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3880,12 +3994,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3880 } 3994 }
3881 break; 3995 break;
3882 case TARGET_NR_stat: 3996 case TARGET_NR_stat:
3883 - p = lock_user_string(arg1); 3997 + if (!(p = lock_user_string(arg1)))
  3998 + goto efault;
3884 ret = get_errno(stat(path(p), &st)); 3999 ret = get_errno(stat(path(p), &st));
3885 unlock_user(p, arg1, 0); 4000 unlock_user(p, arg1, 0);
3886 goto do_stat; 4001 goto do_stat;
3887 case TARGET_NR_lstat: 4002 case TARGET_NR_lstat:
3888 - p = lock_user_string(arg1); 4003 + if (!(p = lock_user_string(arg1)))
  4004 + goto efault;
3889 ret = get_errno(lstat(path(p), &st)); 4005 ret = get_errno(lstat(path(p), &st));
3890 unlock_user(p, arg1, 0); 4006 unlock_user(p, arg1, 0);
3891 goto do_stat; 4007 goto do_stat;
@@ -3896,7 +4012,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3896,7 +4012,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3896 if (!is_error(ret)) { 4012 if (!is_error(ret)) {
3897 struct target_stat *target_st; 4013 struct target_stat *target_st;
3898 4014
3899 - lock_user_struct(target_st, arg2, 0); 4015 + if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
  4016 + goto efault;
3900 #if defined(TARGET_MIPS) || (defined(TARGET_SPARC64) && !defined(TARGET_ABI32)) 4017 #if defined(TARGET_MIPS) || (defined(TARGET_SPARC64) && !defined(TARGET_ABI32))
3901 target_st->st_dev = tswap32(st.st_dev); 4018 target_st->st_dev = tswap32(st.st_dev);
3902 #else 4019 #else
@@ -3979,7 +4096,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3979,7 +4096,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3979 break; 4096 break;
3980 #ifdef TARGET_NR_swapoff 4097 #ifdef TARGET_NR_swapoff
3981 case TARGET_NR_swapoff: 4098 case TARGET_NR_swapoff:
3982 - p = lock_user_string(arg1); 4099 + if (!(p = lock_user_string(arg1)))
  4100 + goto efault;
3983 ret = get_errno(swapoff(p)); 4101 ret = get_errno(swapoff(p));
3984 unlock_user(p, arg1, 0); 4102 unlock_user(p, arg1, 0);
3985 break; 4103 break;
@@ -3991,8 +4109,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -3991,8 +4109,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3991 ret = get_errno(sysinfo(&value)); 4109 ret = get_errno(sysinfo(&value));
3992 if (!is_error(ret) && arg1) 4110 if (!is_error(ret) && arg1)
3993 { 4111 {
3994 - /* ??? __put_user is probably wrong. */  
3995 - lock_user_struct(target_value, arg1, 0); 4112 + if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
  4113 + goto efault;
3996 __put_user(value.uptime, &target_value->uptime); 4114 __put_user(value.uptime, &target_value->uptime);
3997 __put_user(value.loads[0], &target_value->loads[0]); 4115 __put_user(value.loads[0], &target_value->loads[0]);
3998 __put_user(value.loads[1], &target_value->loads[1]); 4116 __put_user(value.loads[1], &target_value->loads[1]);
@@ -4030,7 +4148,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4030,7 +4148,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4030 break; 4148 break;
4031 #endif 4149 #endif
4032 case TARGET_NR_setdomainname: 4150 case TARGET_NR_setdomainname:
4033 - p = lock_user_string(arg1); 4151 + if (!(p = lock_user_string(arg1)))
  4152 + goto efault;
4034 ret = get_errno(setdomainname(p, arg2)); 4153 ret = get_errno(setdomainname(p, arg2));
4035 unlock_user(p, arg1, 0); 4154 unlock_user(p, arg1, 0);
4036 break; 4155 break;
@@ -4039,7 +4158,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4039,7 +4158,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4039 { 4158 {
4040 struct new_utsname * buf; 4159 struct new_utsname * buf;
4041 4160
4042 - lock_user_struct(buf, arg1, 0); 4161 + if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
  4162 + goto efault;
4043 ret = get_errno(sys_uname(buf)); 4163 ret = get_errno(sys_uname(buf));
4044 if (!is_error(ret)) { 4164 if (!is_error(ret)) {
4045 /* Overrite the native machine name with whatever is being 4165 /* Overrite the native machine name with whatever is being
@@ -4124,7 +4244,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4124,7 +4244,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4124 4244
4125 dirp = malloc(count); 4245 dirp = malloc(count);
4126 if (!dirp) { 4246 if (!dirp) {
4127 - ret = -TARGET_EFAULT; 4247 + ret = -TARGET_ENOMEM;
4128 goto fail; 4248 goto fail;
4129 } 4249 }
4130 4250
@@ -4138,7 +4258,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4138,7 +4258,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4138 4258
4139 count1 = 0; 4259 count1 = 0;
4140 de = dirp; 4260 de = dirp;
4141 - target_dirp = lock_user(arg2, count, 0); 4261 + if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
  4262 + goto efault;
4142 tde = target_dirp; 4263 tde = target_dirp;
4143 while (len > 0) { 4264 while (len > 0) {
4144 reclen = de->d_reclen; 4265 reclen = de->d_reclen;
@@ -4157,8 +4278,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4157,8 +4278,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4157 count1 += treclen; 4278 count1 += treclen;
4158 } 4279 }
4159 ret = count1; 4280 ret = count1;
  4281 + unlock_user(target_dirp, arg2, ret);
4160 } 4282 }
4161 - unlock_user(target_dirp, arg2, ret);  
4162 free(dirp); 4283 free(dirp);
4163 } 4284 }
4164 #else 4285 #else
@@ -4166,7 +4287,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4166,7 +4287,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4166 struct dirent *dirp; 4287 struct dirent *dirp;
4167 abi_long count = arg3; 4288 abi_long count = arg3;
4168 4289
4169 - dirp = lock_user(arg2, count, 0); 4290 + if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
  4291 + goto efault;
4170 ret = get_errno(sys_getdents(arg1, dirp, count)); 4292 ret = get_errno(sys_getdents(arg1, dirp, count));
4171 if (!is_error(ret)) { 4293 if (!is_error(ret)) {
4172 struct dirent *de; 4294 struct dirent *de;
@@ -4193,7 +4315,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4193,7 +4315,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4193 { 4315 {
4194 struct dirent64 *dirp; 4316 struct dirent64 *dirp;
4195 abi_long count = arg3; 4317 abi_long count = arg3;
4196 - dirp = lock_user(arg2, count, 0); 4318 + if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
  4319 + goto efault;
4197 ret = get_errno(sys_getdents64(arg1, dirp, count)); 4320 ret = get_errno(sys_getdents64(arg1, dirp, count));
4198 if (!is_error(ret)) { 4321 if (!is_error(ret)) {
4199 struct dirent64 *de; 4322 struct dirent64 *de;
@@ -4229,7 +4352,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4229,7 +4352,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4229 struct pollfd *pfd; 4352 struct pollfd *pfd;
4230 unsigned int i; 4353 unsigned int i;
4231 4354
4232 - target_pfd = lock_user(arg1, sizeof(struct target_pollfd) * nfds, 1); 4355 + target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
  4356 + if (!target_pfd)
  4357 + goto efault;
4233 pfd = alloca(sizeof(struct pollfd) * nfds); 4358 pfd = alloca(sizeof(struct pollfd) * nfds);
4234 for(i = 0; i < nfds; i++) { 4359 for(i = 0; i < nfds; i++) {
4235 pfd[i].fd = tswap32(target_pfd[i].fd); 4360 pfd[i].fd = tswap32(target_pfd[i].fd);
@@ -4258,7 +4383,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4258,7 +4383,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4258 struct iovec *vec; 4383 struct iovec *vec;
4259 4384
4260 vec = alloca(count * sizeof(struct iovec)); 4385 vec = alloca(count * sizeof(struct iovec));
4261 - lock_iovec(vec, arg2, count, 0); 4386 + lock_iovec(VERIFY_WRITE, vec, arg2, count, 0);
4262 ret = get_errno(readv(arg1, vec, count)); 4387 ret = get_errno(readv(arg1, vec, count));
4263 unlock_iovec(vec, arg2, count, 1); 4388 unlock_iovec(vec, arg2, count, 1);
4264 } 4389 }
@@ -4269,7 +4394,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4269,7 +4394,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4269 struct iovec *vec; 4394 struct iovec *vec;
4270 4395
4271 vec = alloca(count * sizeof(struct iovec)); 4396 vec = alloca(count * sizeof(struct iovec));
4272 - lock_iovec(vec, arg2, count, 1); 4397 + lock_iovec(VERIFY_READ, vec, arg2, count, 1);
4273 ret = get_errno(writev(arg1, vec, count)); 4398 ret = get_errno(writev(arg1, vec, count));
4274 unlock_iovec(vec, arg2, count, 0); 4399 unlock_iovec(vec, arg2, count, 0);
4275 } 4400 }
@@ -4292,7 +4417,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4292,7 +4417,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4292 struct sched_param *target_schp; 4417 struct sched_param *target_schp;
4293 struct sched_param schp; 4418 struct sched_param schp;
4294 4419
4295 - lock_user_struct(target_schp, arg2, 1); 4420 + if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
  4421 + goto efault;
4296 schp.sched_priority = tswap32(target_schp->sched_priority); 4422 schp.sched_priority = tswap32(target_schp->sched_priority);
4297 unlock_user_struct(target_schp, arg2, 0); 4423 unlock_user_struct(target_schp, arg2, 0);
4298 ret = get_errno(sched_setparam(arg1, &schp)); 4424 ret = get_errno(sched_setparam(arg1, &schp));
@@ -4304,7 +4430,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4304,7 +4430,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4304 struct sched_param schp; 4430 struct sched_param schp;
4305 ret = get_errno(sched_getparam(arg1, &schp)); 4431 ret = get_errno(sched_getparam(arg1, &schp));
4306 if (!is_error(ret)) { 4432 if (!is_error(ret)) {
4307 - lock_user_struct(target_schp, arg2, 0); 4433 + if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
  4434 + goto efault;
4308 target_schp->sched_priority = tswap32(schp.sched_priority); 4435 target_schp->sched_priority = tswap32(schp.sched_priority);
4309 unlock_user_struct(target_schp, arg2, 1); 4436 unlock_user_struct(target_schp, arg2, 1);
4310 } 4437 }
@@ -4314,7 +4441,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4314,7 +4441,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4314 { 4441 {
4315 struct sched_param *target_schp; 4442 struct sched_param *target_schp;
4316 struct sched_param schp; 4443 struct sched_param schp;
4317 - lock_user_struct(target_schp, arg3, 1); 4444 + if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
  4445 + goto efault;
4318 schp.sched_priority = tswap32(target_schp->sched_priority); 4446 schp.sched_priority = tswap32(target_schp->sched_priority);
4319 unlock_user_struct(target_schp, arg3, 0); 4447 unlock_user_struct(target_schp, arg3, 0);
4320 ret = get_errno(sched_setscheduler(arg1, arg2, &schp)); 4448 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
@@ -4378,18 +4506,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4378,18 +4506,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4378 #ifdef TARGET_NR_pread 4506 #ifdef TARGET_NR_pread
4379 case TARGET_NR_pread: 4507 case TARGET_NR_pread:
4380 page_unprotect_range(arg2, arg3); 4508 page_unprotect_range(arg2, arg3);
4381 - p = lock_user(arg2, arg3, 0); 4509 + if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
  4510 + goto efault;
4382 ret = get_errno(pread(arg1, p, arg3, arg4)); 4511 ret = get_errno(pread(arg1, p, arg3, arg4));
4383 unlock_user(p, arg2, ret); 4512 unlock_user(p, arg2, ret);
4384 break; 4513 break;
4385 case TARGET_NR_pwrite: 4514 case TARGET_NR_pwrite:
4386 - p = lock_user(arg2, arg3, 1); 4515 + if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
  4516 + goto efault;
4387 ret = get_errno(pwrite(arg1, p, arg3, arg4)); 4517 ret = get_errno(pwrite(arg1, p, arg3, arg4));
4388 unlock_user(p, arg2, 0); 4518 unlock_user(p, arg2, 0);
4389 break; 4519 break;
4390 #endif 4520 #endif
4391 case TARGET_NR_getcwd: 4521 case TARGET_NR_getcwd:
4392 - p = lock_user(arg1, arg2, 0); 4522 + if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
  4523 + goto efault;
4393 ret = get_errno(sys_getcwd1(p, arg2)); 4524 ret = get_errno(sys_getcwd1(p, arg2));
4394 unlock_user(p, arg1, ret); 4525 unlock_user(p, arg1, ret);
4395 break; 4526 break;
@@ -4400,9 +4531,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4400,9 +4531,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4400 case TARGET_NR_sigaltstack: 4531 case TARGET_NR_sigaltstack:
4401 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \ 4532 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
4402 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) 4533 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
4403 - ret = do_sigaltstack((struct target_sigaltstack *)arg1,  
4404 - (struct target_sigaltstack *)arg2,  
4405 - get_sp_from_cpustate((CPUState *)cpu_env)); 4534 + ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
4406 break; 4535 break;
4407 #else 4536 #else
4408 goto unimplemented; 4537 goto unimplemented;
@@ -4429,7 +4558,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4429,7 +4558,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4429 ret = get_errno(getrlimit(arg1, &rlim)); 4558 ret = get_errno(getrlimit(arg1, &rlim));
4430 if (!is_error(ret)) { 4559 if (!is_error(ret)) {
4431 struct target_rlimit *target_rlim; 4560 struct target_rlimit *target_rlim;
4432 - lock_user_struct(target_rlim, arg2, 0); 4561 + if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
  4562 + goto efault;
4433 target_rlim->rlim_cur = tswapl(rlim.rlim_cur); 4563 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
4434 target_rlim->rlim_max = tswapl(rlim.rlim_max); 4564 target_rlim->rlim_max = tswapl(rlim.rlim_max);
4435 unlock_user_struct(target_rlim, arg2, 1); 4565 unlock_user_struct(target_rlim, arg2, 1);
@@ -4439,7 +4569,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4439,7 +4569,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4439 #endif 4569 #endif
4440 #ifdef TARGET_NR_truncate64 4570 #ifdef TARGET_NR_truncate64
4441 case TARGET_NR_truncate64: 4571 case TARGET_NR_truncate64:
4442 - p = lock_user_string(arg1); 4572 + if (!(p = lock_user_string(arg1)))
  4573 + goto efault;
4443 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4); 4574 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
4444 unlock_user(p, arg1, 0); 4575 unlock_user(p, arg1, 0);
4445 break; 4576 break;
@@ -4451,14 +4582,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4451,14 +4582,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4451 #endif 4582 #endif
4452 #ifdef TARGET_NR_stat64 4583 #ifdef TARGET_NR_stat64
4453 case TARGET_NR_stat64: 4584 case TARGET_NR_stat64:
4454 - p = lock_user_string(arg1); 4585 + if (!(p = lock_user_string(arg1)))
  4586 + goto efault;
4455 ret = get_errno(stat(path(p), &st)); 4587 ret = get_errno(stat(path(p), &st));
4456 unlock_user(p, arg1, 0); 4588 unlock_user(p, arg1, 0);
4457 goto do_stat64; 4589 goto do_stat64;
4458 #endif 4590 #endif
4459 #ifdef TARGET_NR_lstat64 4591 #ifdef TARGET_NR_lstat64
4460 case TARGET_NR_lstat64: 4592 case TARGET_NR_lstat64:
4461 - p = lock_user_string(arg1); 4593 + if (!(p = lock_user_string(arg1)))
  4594 + goto efault;
4462 ret = get_errno(lstat(path(p), &st)); 4595 ret = get_errno(lstat(path(p), &st));
4463 unlock_user(p, arg1, 0); 4596 unlock_user(p, arg1, 0);
4464 goto do_stat64; 4597 goto do_stat64;
@@ -4472,52 +4605,53 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4472,52 +4605,53 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4472 #ifdef TARGET_ARM 4605 #ifdef TARGET_ARM
4473 if (((CPUARMState *)cpu_env)->eabi) { 4606 if (((CPUARMState *)cpu_env)->eabi) {
4474 struct target_eabi_stat64 *target_st; 4607 struct target_eabi_stat64 *target_st;
4475 - lock_user_struct(target_st, arg2, 1); 4608 +
  4609 + if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
  4610 + goto efault;
4476 memset(target_st, 0, sizeof(struct target_eabi_stat64)); 4611 memset(target_st, 0, sizeof(struct target_eabi_stat64));
4477 - /* put_user is probably wrong. */  
4478 - put_user(st.st_dev, &target_st->st_dev);  
4479 - put_user(st.st_ino, &target_st->st_ino); 4612 + __put_user(st.st_dev, &target_st->st_dev);
  4613 + __put_user(st.st_ino, &target_st->st_ino);
4480 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 4614 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4481 - put_user(st.st_ino, &target_st->__st_ino);  
4482 -#endif  
4483 - put_user(st.st_mode, &target_st->st_mode);  
4484 - put_user(st.st_nlink, &target_st->st_nlink);  
4485 - put_user(st.st_uid, &target_st->st_uid);  
4486 - put_user(st.st_gid, &target_st->st_gid);  
4487 - put_user(st.st_rdev, &target_st->st_rdev);  
4488 - /* XXX: better use of kernel struct */  
4489 - put_user(st.st_size, &target_st->st_size);  
4490 - put_user(st.st_blksize, &target_st->st_blksize);  
4491 - put_user(st.st_blocks, &target_st->st_blocks);  
4492 - put_user(st.st_atime, &target_st->target_st_atime);  
4493 - put_user(st.st_mtime, &target_st->target_st_mtime);  
4494 - put_user(st.st_ctime, &target_st->target_st_ctime);  
4495 - unlock_user_struct(target_st, arg2, 0); 4615 + __put_user(st.st_ino, &target_st->__st_ino);
  4616 +#endif
  4617 + __put_user(st.st_mode, &target_st->st_mode);
  4618 + __put_user(st.st_nlink, &target_st->st_nlink);
  4619 + __put_user(st.st_uid, &target_st->st_uid);
  4620 + __put_user(st.st_gid, &target_st->st_gid);
  4621 + __put_user(st.st_rdev, &target_st->st_rdev);
  4622 + __put_user(st.st_size, &target_st->st_size);
  4623 + __put_user(st.st_blksize, &target_st->st_blksize);
  4624 + __put_user(st.st_blocks, &target_st->st_blocks);
  4625 + __put_user(st.st_atime, &target_st->target_st_atime);
  4626 + __put_user(st.st_mtime, &target_st->target_st_mtime);
  4627 + __put_user(st.st_ctime, &target_st->target_st_ctime);
  4628 + unlock_user_struct(target_st, arg2, 1);
4496 } else 4629 } else
4497 #endif 4630 #endif
4498 { 4631 {
4499 struct target_stat64 *target_st; 4632 struct target_stat64 *target_st;
4500 - lock_user_struct(target_st, arg2, 1); 4633 +
  4634 + if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
  4635 + goto efault;
4501 memset(target_st, 0, sizeof(struct target_stat64)); 4636 memset(target_st, 0, sizeof(struct target_stat64));
4502 - /* ??? put_user is probably wrong. */  
4503 - put_user(st.st_dev, &target_st->st_dev);  
4504 - put_user(st.st_ino, &target_st->st_ino); 4637 + __put_user(st.st_dev, &target_st->st_dev);
  4638 + __put_user(st.st_ino, &target_st->st_ino);
4505 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 4639 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4506 - put_user(st.st_ino, &target_st->__st_ino); 4640 + __put_user(st.st_ino, &target_st->__st_ino);
4507 #endif 4641 #endif
4508 - put_user(st.st_mode, &target_st->st_mode);  
4509 - put_user(st.st_nlink, &target_st->st_nlink);  
4510 - put_user(st.st_uid, &target_st->st_uid);  
4511 - put_user(st.st_gid, &target_st->st_gid);  
4512 - put_user(st.st_rdev, &target_st->st_rdev); 4642 + __put_user(st.st_mode, &target_st->st_mode);
  4643 + __put_user(st.st_nlink, &target_st->st_nlink);
  4644 + __put_user(st.st_uid, &target_st->st_uid);
  4645 + __put_user(st.st_gid, &target_st->st_gid);
  4646 + __put_user(st.st_rdev, &target_st->st_rdev);
4513 /* XXX: better use of kernel struct */ 4647 /* XXX: better use of kernel struct */
4514 - put_user(st.st_size, &target_st->st_size);  
4515 - put_user(st.st_blksize, &target_st->st_blksize);  
4516 - put_user(st.st_blocks, &target_st->st_blocks);  
4517 - put_user(st.st_atime, &target_st->target_st_atime);  
4518 - put_user(st.st_mtime, &target_st->target_st_mtime);  
4519 - put_user(st.st_ctime, &target_st->target_st_ctime);  
4520 - unlock_user_struct(target_st, arg2, 0); 4648 + __put_user(st.st_size, &target_st->st_size);
  4649 + __put_user(st.st_blksize, &target_st->st_blksize);
  4650 + __put_user(st.st_blocks, &target_st->st_blocks);
  4651 + __put_user(st.st_atime, &target_st->target_st_atime);
  4652 + __put_user(st.st_mtime, &target_st->target_st_mtime);
  4653 + __put_user(st.st_ctime, &target_st->target_st_ctime);
  4654 + unlock_user_struct(target_st, arg2, 1);
4521 } 4655 }
4522 } 4656 }
4523 } 4657 }
@@ -4525,7 +4659,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4525,7 +4659,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4525 #endif 4659 #endif
4526 #ifdef USE_UID16 4660 #ifdef USE_UID16
4527 case TARGET_NR_lchown: 4661 case TARGET_NR_lchown:
4528 - p = lock_user_string(arg1); 4662 + if (!(p = lock_user_string(arg1)))
  4663 + goto efault;
4529 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3))); 4664 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
4530 unlock_user(p, arg1, 0); 4665 unlock_user(p, arg1, 0);
4531 break; 4666 break;
@@ -4557,7 +4692,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4557,7 +4692,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4557 grouplist = alloca(gidsetsize * sizeof(gid_t)); 4692 grouplist = alloca(gidsetsize * sizeof(gid_t));
4558 ret = get_errno(getgroups(gidsetsize, grouplist)); 4693 ret = get_errno(getgroups(gidsetsize, grouplist));
4559 if (!is_error(ret)) { 4694 if (!is_error(ret)) {
4560 - target_grouplist = lock_user(arg2, gidsetsize * 2, 0); 4695 + target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
  4696 + if (!target_grouplist)
  4697 + goto efault;
4561 for(i = 0;i < gidsetsize; i++) 4698 for(i = 0;i < gidsetsize; i++)
4562 target_grouplist[i] = tswap16(grouplist[i]); 4699 target_grouplist[i] = tswap16(grouplist[i]);
4563 unlock_user(target_grouplist, arg2, gidsetsize * 2); 4700 unlock_user(target_grouplist, arg2, gidsetsize * 2);
@@ -4572,7 +4709,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4572,7 +4709,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4572 int i; 4709 int i;
4573 4710
4574 grouplist = alloca(gidsetsize * sizeof(gid_t)); 4711 grouplist = alloca(gidsetsize * sizeof(gid_t));
4575 - target_grouplist = lock_user(arg2, gidsetsize * 2, 1); 4712 + target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
  4713 + if (!target_grouplist) {
  4714 + ret = -TARGET_EFAULT;
  4715 + goto fail;
  4716 + }
4576 for(i = 0;i < gidsetsize; i++) 4717 for(i = 0;i < gidsetsize; i++)
4577 grouplist[i] = tswap16(target_grouplist[i]); 4718 grouplist[i] = tswap16(target_grouplist[i]);
4578 unlock_user(target_grouplist, arg2, 0); 4719 unlock_user(target_grouplist, arg2, 0);
@@ -4584,18 +4725,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4584,18 +4725,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4584 break; 4725 break;
4585 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) 4726 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
4586 case TARGET_NR_fchownat: 4727 case TARGET_NR_fchownat:
4587 - if (!arg2) {  
4588 - ret = -TARGET_EFAULT;  
4589 - goto fail;  
4590 - }  
4591 - p = lock_user_string(arg2);  
4592 - if (!access_ok(VERIFY_READ, p, 1))  
4593 - /* Don't "goto fail" so that cleanup can happen. */  
4594 - ret = -TARGET_EFAULT;  
4595 - else  
4596 - ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));  
4597 - if (p)  
4598 - unlock_user(p, arg2, 0); 4728 + if (!(p = lock_user_string(arg2)))
  4729 + goto efault;
  4730 + ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
  4731 + unlock_user(p, arg2, 0);
4599 break; 4732 break;
4600 #endif 4733 #endif
4601 #ifdef TARGET_NR_setresuid 4734 #ifdef TARGET_NR_setresuid
@@ -4639,7 +4772,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4639,7 +4772,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4639 break; 4772 break;
4640 #endif 4773 #endif
4641 case TARGET_NR_chown: 4774 case TARGET_NR_chown:
4642 - p = lock_user_string(arg1); 4775 + if (!(p = lock_user_string(arg1)))
  4776 + goto efault;
4643 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3))); 4777 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
4644 unlock_user(p, arg1, 0); 4778 unlock_user(p, arg1, 0);
4645 break; 4779 break;
@@ -4659,7 +4793,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4659,7 +4793,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4659 4793
4660 #ifdef TARGET_NR_lchown32 4794 #ifdef TARGET_NR_lchown32
4661 case TARGET_NR_lchown32: 4795 case TARGET_NR_lchown32:
4662 - p = lock_user_string(arg1); 4796 + if (!(p = lock_user_string(arg1)))
  4797 + goto efault;
4663 ret = get_errno(lchown(p, arg2, arg3)); 4798 ret = get_errno(lchown(p, arg2, arg3));
4664 unlock_user(p, arg1, 0); 4799 unlock_user(p, arg1, 0);
4665 break; 4800 break;
@@ -4705,7 +4840,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4705,7 +4840,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4705 grouplist = alloca(gidsetsize * sizeof(gid_t)); 4840 grouplist = alloca(gidsetsize * sizeof(gid_t));
4706 ret = get_errno(getgroups(gidsetsize, grouplist)); 4841 ret = get_errno(getgroups(gidsetsize, grouplist));
4707 if (!is_error(ret)) { 4842 if (!is_error(ret)) {
4708 - target_grouplist = lock_user(arg2, gidsetsize * 4, 0); 4843 + target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
  4844 + if (!target_grouplist) {
  4845 + ret = -TARGET_EFAULT;
  4846 + goto fail;
  4847 + }
4709 for(i = 0;i < gidsetsize; i++) 4848 for(i = 0;i < gidsetsize; i++)
4710 target_grouplist[i] = tswap32(grouplist[i]); 4849 target_grouplist[i] = tswap32(grouplist[i]);
4711 unlock_user(target_grouplist, arg2, gidsetsize * 4); 4850 unlock_user(target_grouplist, arg2, gidsetsize * 4);
@@ -4722,7 +4861,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4722,7 +4861,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4722 int i; 4861 int i;
4723 4862
4724 grouplist = alloca(gidsetsize * sizeof(gid_t)); 4863 grouplist = alloca(gidsetsize * sizeof(gid_t));
4725 - target_grouplist = lock_user(arg2, gidsetsize * 4, 1); 4864 + target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
  4865 + if (!target_grouplist) {
  4866 + ret = -TARGET_EFAULT;
  4867 + goto fail;
  4868 + }
4726 for(i = 0;i < gidsetsize; i++) 4869 for(i = 0;i < gidsetsize; i++)
4727 grouplist[i] = tswap32(target_grouplist[i]); 4870 grouplist[i] = tswap32(target_grouplist[i]);
4728 unlock_user(target_grouplist, arg2, 0); 4871 unlock_user(target_grouplist, arg2, 0);
@@ -4773,7 +4916,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4773,7 +4916,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4773 #endif 4916 #endif
4774 #ifdef TARGET_NR_chown32 4917 #ifdef TARGET_NR_chown32
4775 case TARGET_NR_chown32: 4918 case TARGET_NR_chown32:
4776 - p = lock_user_string(arg1); 4919 + if (!(p = lock_user_string(arg1)))
  4920 + goto efault;
4777 ret = get_errno(chown(p, arg2, arg3)); 4921 ret = get_errno(chown(p, arg2, arg3));
4778 unlock_user(p, arg1, 0); 4922 unlock_user(p, arg1, 0);
4779 break; 4923 break;
@@ -4843,7 +4987,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4843,7 +4987,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4843 case TARGET_F_GETLK64: 4987 case TARGET_F_GETLK64:
4844 #ifdef TARGET_ARM 4988 #ifdef TARGET_ARM
4845 if (((CPUARMState *)cpu_env)->eabi) { 4989 if (((CPUARMState *)cpu_env)->eabi) {
4846 - lock_user_struct(target_efl, arg3, 1); 4990 + if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) {
  4991 + ret = -TARGET_EFAULT;
  4992 + goto fail;
  4993 + }
4847 fl.l_type = tswap16(target_efl->l_type); 4994 fl.l_type = tswap16(target_efl->l_type);
4848 fl.l_whence = tswap16(target_efl->l_whence); 4995 fl.l_whence = tswap16(target_efl->l_whence);
4849 fl.l_start = tswap64(target_efl->l_start); 4996 fl.l_start = tswap64(target_efl->l_start);
@@ -4853,7 +5000,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4853,7 +5000,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4853 } else 5000 } else
4854 #endif 5001 #endif
4855 { 5002 {
4856 - lock_user_struct(target_fl, arg3, 1); 5003 + if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) {
  5004 + ret = -TARGET_EFAULT;
  5005 + goto fail;
  5006 + }
4857 fl.l_type = tswap16(target_fl->l_type); 5007 fl.l_type = tswap16(target_fl->l_type);
4858 fl.l_whence = tswap16(target_fl->l_whence); 5008 fl.l_whence = tswap16(target_fl->l_whence);
4859 fl.l_start = tswap64(target_fl->l_start); 5009 fl.l_start = tswap64(target_fl->l_start);
@@ -4865,7 +5015,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4865,7 +5015,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4865 if (ret == 0) { 5015 if (ret == 0) {
4866 #ifdef TARGET_ARM 5016 #ifdef TARGET_ARM
4867 if (((CPUARMState *)cpu_env)->eabi) { 5017 if (((CPUARMState *)cpu_env)->eabi) {
4868 - lock_user_struct(target_efl, arg3, 0); 5018 + if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) {
  5019 + ret = -TARGET_EFAULT;
  5020 + goto fail;
  5021 + }
4869 target_efl->l_type = tswap16(fl.l_type); 5022 target_efl->l_type = tswap16(fl.l_type);
4870 target_efl->l_whence = tswap16(fl.l_whence); 5023 target_efl->l_whence = tswap16(fl.l_whence);
4871 target_efl->l_start = tswap64(fl.l_start); 5024 target_efl->l_start = tswap64(fl.l_start);
@@ -4875,7 +5028,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4875,7 +5028,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4875 } else 5028 } else
4876 #endif 5029 #endif
4877 { 5030 {
4878 - lock_user_struct(target_fl, arg3, 0); 5031 + if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) {
  5032 + ret = -TARGET_EFAULT;
  5033 + goto fail;
  5034 + }
4879 target_fl->l_type = tswap16(fl.l_type); 5035 target_fl->l_type = tswap16(fl.l_type);
4880 target_fl->l_whence = tswap16(fl.l_whence); 5036 target_fl->l_whence = tswap16(fl.l_whence);
4881 target_fl->l_start = tswap64(fl.l_start); 5037 target_fl->l_start = tswap64(fl.l_start);
@@ -4890,7 +5046,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4890,7 +5046,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4890 case TARGET_F_SETLKW64: 5046 case TARGET_F_SETLKW64:
4891 #ifdef TARGET_ARM 5047 #ifdef TARGET_ARM
4892 if (((CPUARMState *)cpu_env)->eabi) { 5048 if (((CPUARMState *)cpu_env)->eabi) {
4893 - lock_user_struct(target_efl, arg3, 1); 5049 + if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) {
  5050 + ret = -TARGET_EFAULT;
  5051 + goto fail;
  5052 + }
4894 fl.l_type = tswap16(target_efl->l_type); 5053 fl.l_type = tswap16(target_efl->l_type);
4895 fl.l_whence = tswap16(target_efl->l_whence); 5054 fl.l_whence = tswap16(target_efl->l_whence);
4896 fl.l_start = tswap64(target_efl->l_start); 5055 fl.l_start = tswap64(target_efl->l_start);
@@ -4900,7 +5059,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4900,7 +5059,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4900 } else 5059 } else
4901 #endif 5060 #endif
4902 { 5061 {
4903 - lock_user_struct(target_fl, arg3, 1); 5062 + if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) {
  5063 + ret = -TARGET_EFAULT;
  5064 + goto fail;
  5065 + }
4904 fl.l_type = tswap16(target_fl->l_type); 5066 fl.l_type = tswap16(target_fl->l_type);
4905 fl.l_whence = tswap16(target_fl->l_whence); 5067 fl.l_whence = tswap16(target_fl->l_whence);
4906 fl.l_start = tswap64(target_fl->l_start); 5068 fl.l_start = tswap64(target_fl->l_start);
@@ -4998,8 +5160,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -4998,8 +5160,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4998 5160
4999 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) 5161 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5000 case TARGET_NR_set_tid_address: 5162 case TARGET_NR_set_tid_address:
5001 - ret = get_errno(set_tid_address((int *) arg1));  
5002 - break; 5163 + ret = get_errno(set_tid_address((int *)g2h(arg1)));
  5164 + break;
5003 #endif 5165 #endif
5004 5166
5005 #if defined(TARGET_NR_tkill) && defined(__NR_tkill) 5167 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
@@ -5028,14 +5190,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -5028,14 +5190,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5028 if (!arg2) 5190 if (!arg2)
5029 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4)); 5191 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5030 else { 5192 else {
5031 - p = lock_user_string(arg2);  
5032 - if (!access_ok(VERIFY_READ, p, 1))  
5033 - /* Don't "goto fail" so that cleanup can happen. */ 5193 + if (!(p = lock_user_string(arg2))) {
5034 ret = -TARGET_EFAULT; 5194 ret = -TARGET_EFAULT;
5035 - else  
5036 - ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));  
5037 - if (p)  
5038 - unlock_user(p, arg2, 0); 5195 + goto fail;
  5196 + }
  5197 + ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
  5198 + unlock_user(p, arg2, 0);
5039 } 5199 }
5040 } 5200 }
5041 break; 5201 break;
@@ -5050,11 +5210,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -5050,11 +5210,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5050 ret = -TARGET_ENOSYS; 5210 ret = -TARGET_ENOSYS;
5051 break; 5211 break;
5052 } 5212 }
5053 - fail: 5213 +fail:
5054 #ifdef DEBUG 5214 #ifdef DEBUG
5055 gemu_log(" = %ld\n", ret); 5215 gemu_log(" = %ld\n", ret);
5056 #endif 5216 #endif
5057 if(do_strace) 5217 if(do_strace)
5058 print_syscall_ret(num, ret); 5218 print_syscall_ret(num, ret);
5059 return ret; 5219 return ret;
  5220 +efault:
  5221 + ret = -TARGET_EFAULT;
  5222 + goto fail;
5060 } 5223 }
linux-user/uaccess.c 0 โ†’ 100644
  1 +/* User memory access */
  2 +#include <stdio.h>
  3 +#include <string.h>
  4 +
  5 +#include "qemu.h"
  6 +
  7 +/* copy_from_user() and copy_to_user() are usually used to copy data
  8 + * buffers between the target and host. These internally perform
  9 + * locking/unlocking of the memory.
  10 + */
  11 +abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
  12 +{
  13 + abi_long ret = 0;
  14 + void *ghptr;
  15 +
  16 + if ((ghptr = lock_user(VERIFY_READ, gaddr, len, 1))) {
  17 + memcpy(hptr, ghptr, len);
  18 + unlock_user(ghptr, gaddr, 0);
  19 + } else
  20 + ret = -TARGET_EFAULT;
  21 +
  22 + return ret;
  23 +}
  24 +
  25 +
  26 +abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len)
  27 +{
  28 + abi_long ret = 0;
  29 + void *ghptr;
  30 +
  31 + if ((ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0))) {
  32 + memcpy(ghptr, hptr, len);
  33 + unlock_user(ghptr, gaddr, len);
  34 + } else
  35 + ret = -TARGET_EFAULT;
  36 +
  37 + return ret;
  38 +}
  39 +
  40 +
  41 +/* Return the length of a string in target memory. */
  42 +/* FIXME - this doesn't check access_ok() - it's rather complicated to
  43 + * do it correctly because we need to check the bytes in a page and then
  44 + * skip to the next page and check the bytes there until we find the
  45 + * terminator. There should be a general function to do this that
  46 + * can look for any byte terminator in a buffer - not strlen().
  47 + */
  48 +abi_long target_strlen(abi_ulong gaddr)
  49 +{
  50 + return strlen(g2h(gaddr));
  51 +}
linux-user/vm86.c
@@ -64,7 +64,9 @@ void save_v86_state(CPUX86State *env) @@ -64,7 +64,9 @@ void save_v86_state(CPUX86State *env)
64 TaskState *ts = env->opaque; 64 TaskState *ts = env->opaque;
65 struct target_vm86plus_struct * target_v86; 65 struct target_vm86plus_struct * target_v86;
66 66
67 - lock_user_struct(target_v86, ts->target_v86, 0); 67 + if (!lock_user_struct(VERIFY_WRITE, target_v86, ts->target_v86, 0))
  68 + /* FIXME - should return an error */
  69 + return;
68 /* put the VM86 registers in the userspace register structure */ 70 /* put the VM86 registers in the userspace register structure */
69 target_v86->regs.eax = tswap32(env->regs[R_EAX]); 71 target_v86->regs.eax = tswap32(env->regs[R_EAX]);
70 target_v86->regs.ebx = tswap32(env->regs[R_EBX]); 72 target_v86->regs.ebx = tswap32(env->regs[R_EBX]);
@@ -424,7 +426,8 @@ int do_vm86(CPUX86State *env, long subfunction, abi_ulong vm86_addr) @@ -424,7 +426,8 @@ int do_vm86(CPUX86State *env, long subfunction, abi_ulong vm86_addr)
424 ts->vm86_saved_regs.gs = env->segs[R_GS].selector; 426 ts->vm86_saved_regs.gs = env->segs[R_GS].selector;
425 427
426 ts->target_v86 = vm86_addr; 428 ts->target_v86 = vm86_addr;
427 - lock_user_struct(target_v86, vm86_addr, 1); 429 + if (!lock_user_struct(VERIFY_READ, target_v86, vm86_addr, 1))
  430 + return -EFAULT;
428 /* build vm86 CPU state */ 431 /* build vm86 CPU state */
429 ts->v86flags = tswap32(target_v86->regs.eflags); 432 ts->v86flags = tswap32(target_v86->regs.eflags);
430 env->eflags = (env->eflags & ~SAFE_MASK) | 433 env->eflags = (env->eflags & ~SAFE_MASK) |
m68k-semi.c
@@ -107,7 +107,9 @@ static void translate_stat(CPUState *env, target_ulong addr, struct stat *s) @@ -107,7 +107,9 @@ static void translate_stat(CPUState *env, target_ulong addr, struct stat *s)
107 { 107 {
108 struct m68k_gdb_stat *p; 108 struct m68k_gdb_stat *p;
109 109
110 - p = lock_user(addr, sizeof(struct m68k_gdb_stat), 0); 110 + if (!(p = lock_user(VERIFY_WRITE, addr, sizeof(struct m68k_gdb_stat), 0)))
  111 + /* FIXME - should this return an error code? */
  112 + return;
111 p->gdb_st_dev = cpu_to_be32(s->st_dev); 113 p->gdb_st_dev = cpu_to_be32(s->st_dev);
112 p->gdb_st_ino = cpu_to_be32(s->st_ino); 114 p->gdb_st_ino = cpu_to_be32(s->st_ino);
113 p->gdb_st_mode = cpu_to_be32(s->st_mode); 115 p->gdb_st_mode = cpu_to_be32(s->st_mode);
@@ -168,9 +170,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) @@ -168,9 +170,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
168 ARG(2), ARG(3)); 170 ARG(2), ARG(3));
169 return; 171 return;
170 } else { 172 } else {
171 - p = lock_user_string(ARG(0));  
172 - result = open(p, translate_openflags(ARG(2)), ARG(3));  
173 - unlock_user(p, ARG(0), 0); 173 + if (!(p = lock_user_string(ARG(0)))) {
  174 + /* FIXME - check error code? */
  175 + result = -1;
  176 + } else {
  177 + result = open(p, translate_openflags(ARG(2)), ARG(3));
  178 + unlock_user(p, ARG(0), 0);
  179 + }
174 } 180 }
175 break; 181 break;
176 case HOSTED_CLOSE: 182 case HOSTED_CLOSE:
@@ -196,9 +202,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) @@ -196,9 +202,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
196 ARG(0), ARG(1), len); 202 ARG(0), ARG(1), len);
197 return; 203 return;
198 } else { 204 } else {
199 - p = lock_user(ARG(1), len, 0);  
200 - result = read(ARG(0), p, len);  
201 - unlock_user(p, ARG(1), len); 205 + if (!(p = lock_user(VERIFY_WRITE, ARG(1), len, 0))) {
  206 + /* FIXME - check error code? */
  207 + result = -1;
  208 + } else {
  209 + result = read(ARG(0), p, len);
  210 + unlock_user(p, ARG(1), len);
  211 + }
202 } 212 }
203 break; 213 break;
204 case HOSTED_WRITE: 214 case HOSTED_WRITE:
@@ -208,9 +218,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) @@ -208,9 +218,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
208 ARG(0), ARG(1), len); 218 ARG(0), ARG(1), len);
209 return; 219 return;
210 } else { 220 } else {
211 - p = lock_user(ARG(1), len, 1);  
212 - result = write(ARG(0), p, len);  
213 - unlock_user(p, ARG(0), 0); 221 + if (!(p = lock_user(VERIFY_READ, ARG(1), len, 1))) {
  222 + /* FIXME - check error code? */
  223 + result = -1;
  224 + } else {
  225 + result = write(ARG(0), p, len);
  226 + unlock_user(p, ARG(0), 0);
  227 + }
214 } 228 }
215 break; 229 break;
216 case HOSTED_LSEEK: 230 case HOSTED_LSEEK:
@@ -237,7 +251,12 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) @@ -237,7 +251,12 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
237 } else { 251 } else {
238 p = lock_user_string(ARG(0)); 252 p = lock_user_string(ARG(0));
239 q = lock_user_string(ARG(2)); 253 q = lock_user_string(ARG(2));
240 - result = rename(p, q); 254 + if (!p || !q) {
  255 + /* FIXME - check error code? */
  256 + result = -1;
  257 + } else {
  258 + result = rename(p, q);
  259 + }
241 unlock_user(p, ARG(0), 0); 260 unlock_user(p, ARG(0), 0);
242 unlock_user(q, ARG(2), 0); 261 unlock_user(q, ARG(2), 0);
243 } 262 }
@@ -248,9 +267,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) @@ -248,9 +267,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
248 ARG(0), (int)ARG(1)); 267 ARG(0), (int)ARG(1));
249 return; 268 return;
250 } else { 269 } else {
251 - p = lock_user_string(ARG(0));  
252 - result = unlink(p);  
253 - unlock_user(p, ARG(0), 0); 270 + if (!(p = lock_user_string(ARG(0)))) {
  271 + /* FIXME - check error code? */
  272 + result = -1;
  273 + } else {
  274 + result = unlink(p);
  275 + unlock_user(p, ARG(0), 0);
  276 + }
254 } 277 }
255 break; 278 break;
256 case HOSTED_STAT: 279 case HOSTED_STAT:
@@ -260,9 +283,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) @@ -260,9 +283,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
260 return; 283 return;
261 } else { 284 } else {
262 struct stat s; 285 struct stat s;
263 - p = lock_user_string(ARG(0));  
264 - result = stat(p, &s);  
265 - unlock_user(p, ARG(0), 0); 286 + if (!(p = lock_user_string(ARG(0)))) {
  287 + /* FIXME - check error code? */
  288 + result = -1;
  289 + } else {
  290 + result = stat(p, &s);
  291 + unlock_user(p, ARG(0), 0);
  292 + }
266 if (result == 0) { 293 if (result == 0) {
267 translate_stat(env, ARG(2), &s); 294 translate_stat(env, ARG(2), &s);
268 } 295 }
@@ -291,10 +318,15 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) @@ -291,10 +318,15 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
291 struct gdb_timeval *p; 318 struct gdb_timeval *p;
292 result = qemu_gettimeofday(&tv); 319 result = qemu_gettimeofday(&tv);
293 if (result != 0) { 320 if (result != 0) {
294 - p = lock_user(ARG(0), sizeof(struct gdb_timeval), 0);  
295 - p->tv_sec = cpu_to_be32(tv.tv_sec);  
296 - p->tv_usec = cpu_to_be64(tv.tv_usec);  
297 - unlock_user(p, ARG(0), sizeof(struct gdb_timeval)); 321 + if (!(p = lock_user(VERIFY_WRITE,
  322 + ARG(0), sizeof(struct gdb_timeval), 0))) {
  323 + /* FIXME - check error code? */
  324 + result = -1;
  325 + } else {
  326 + p->tv_sec = cpu_to_be32(tv.tv_sec);
  327 + p->tv_usec = cpu_to_be64(tv.tv_usec);
  328 + unlock_user(p, ARG(0), sizeof(struct gdb_timeval));
  329 + }
298 } 330 }
299 } 331 }
300 break; 332 break;
@@ -312,9 +344,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) @@ -312,9 +344,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
312 ARG(0), (int)ARG(1)); 344 ARG(0), (int)ARG(1));
313 return; 345 return;
314 } else { 346 } else {
315 - p = lock_user_string(ARG(0));  
316 - result = system(p);  
317 - unlock_user(p, ARG(0), 0); 347 + if (!(p = lock_user_string(ARG(0)))) {
  348 + /* FIXME - check error code? */
  349 + result = -1;
  350 + } else {
  351 + result = system(p);
  352 + unlock_user(p, ARG(0), 0);
  353 + }
318 } 354 }
319 break; 355 break;
320 case HOSTED_INIT_SIM: 356 case HOSTED_INIT_SIM:
softmmu-semi.h
@@ -41,7 +41,7 @@ static void *softmmu_lock_user(CPUState *env, uint32_t addr, uint32_t len, @@ -41,7 +41,7 @@ static void *softmmu_lock_user(CPUState *env, uint32_t addr, uint32_t len,
41 cpu_memory_rw_debug(env, addr, p, len, 0); 41 cpu_memory_rw_debug(env, addr, p, len, 0);
42 return p; 42 return p;
43 } 43 }
44 -#define lock_user(p, len, copy) softmmu_lock_user(env, p, len, copy) 44 +#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
45 static char *softmmu_lock_user_string(CPUState *env, uint32_t addr) 45 static char *softmmu_lock_user_string(CPUState *env, uint32_t addr)
46 { 46 {
47 char *p; 47 char *p;