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 260  
261 261 ifdef CONFIG_LINUX_USER
262 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 264 LIBS+= $(AIOLIBS)
265 265 ifdef TARGET_HAS_BFLT
266 266 OBJS+= flatload.o
... ...
arm-semi.c
... ... @@ -184,9 +184,11 @@ uint32_t do_arm_semihosting(CPUState *env)
184 184 args = env->regs[1];
185 185 switch (nr) {
186 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 190 if (ARG(1) >= 12)
189   - return (uint32_t)-1;
  191 + return (uint32_t)-1;
190 192 if (strcmp(s, ":tt") == 0) {
191 193 if (ARG(1) < 4)
192 194 return STDIN_FILENO;
... ... @@ -221,7 +223,9 @@ uint32_t do_arm_semihosting(CPUState *env)
221 223 }
222 224 }
223 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 229 len = strlen(s);
226 230 if (use_gdb_syscalls()) {
227 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 242 gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len);
239 243 return env->regs[0];
240 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 248 ret = set_swi_errno(ts, write(ARG(0), s, len));
243 249 unlock_user(s, ARG(1), 0);
244 250 if (ret == (uint32_t)-1)
... ... @@ -252,7 +258,9 @@ uint32_t do_arm_semihosting(CPUState *env)
252 258 gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len);
253 259 return env->regs[0];
254 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 264 do
257 265 ret = set_swi_errno(ts, read(ARG(0), s, len));
258 266 while (ret == -1 && errno == EINTR);
... ... @@ -301,7 +309,9 @@ uint32_t do_arm_semihosting(CPUState *env)
301 309 gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1);
302 310 ret = env->regs[0];
303 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 315 ret = set_swi_errno(ts, remove(s));
306 316 unlock_user(s, ARG(0), 0);
307 317 }
... ... @@ -315,9 +325,15 @@ uint32_t do_arm_semihosting(CPUState *env)
315 325 char *s2;
316 326 s = lock_user_string(ARG(0));
317 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 337 return ret;
322 338 }
323 339 case SYS_CLOCK:
... ... @@ -329,7 +345,9 @@ uint32_t do_arm_semihosting(CPUState *env)
329 345 gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1);
330 346 return env->regs[0];
331 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 351 ret = set_swi_errno(ts, system(s));
334 352 unlock_user(s, ARG(0), 0);
335 353 }
... ... @@ -346,7 +364,11 @@ uint32_t do_arm_semihosting(CPUState *env)
346 364 char **arg = ts->info->host_argv;
347 365 int len = ARG(1);
348 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 373 s = cmdline_buffer;
352 374 while (*arg && len > 2) {
... ... @@ -402,7 +424,9 @@ uint32_t do_arm_semihosting(CPUState *env)
402 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 430 ptr[0] = tswap32(ts->heap_base);
407 431 ptr[1] = tswap32(ts->heap_limit);
408 432 ptr[2] = tswap32(ts->stack_base);
... ... @@ -410,7 +434,9 @@ uint32_t do_arm_semihosting(CPUState *env)
410 434 unlock_user(ptr, ARG(0), 16);
411 435 #else
412 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 440 /* TODO: Make this use the limit of the loaded application. */
415 441 ptr[0] = tswap32(limit / 2);
416 442 ptr[1] = tswap32(limit);
... ...
... ... @@ -2510,13 +2510,19 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
2510 2510 if (is_write) {
2511 2511 if (!(flags & PAGE_WRITE))
2512 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 2517 memcpy(p, buf, len);
2515 2518 unlock_user(p, addr, len);
2516 2519 } else {
2517 2520 if (!(flags & PAGE_READ))
2518 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 2526 memcpy(buf, p, len);
2521 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 677 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
678 678 if (bprm->page[i]) {
679 679 info->rss++;
680   -
  680 + /* FIXME - check return value of memcpy_to_target() for failure */
681 681 memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
682 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 760 size_t len = strlen(k_platform) + 1;
761 761 sp -= (len + n - 1) & ~(n - 1);
762 762 u_platform = sp;
  763 + /* FIXME - check return value of memcpy_to_target() for failure */
763 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 108 void *buf;
109 109 int ret;
110 110  
111   - buf = lock_user(ptr, len, 0);
  111 + buf = lock_user(VERIFY_WRITE, ptr, len, 0);
112 112 ret = pread(fd, buf, len, offset);
113 113 unlock_user(buf, ptr, len);
114 114 return ret;
... ...
linux-user/linuxload.c
... ... @@ -13,14 +13,17 @@
13 13 #define NGROUPS 32
14 14  
15 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 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 24 memcpy(host_ptr, src, len);
23 25 unlock_user(host_ptr, dest, 1);
  26 + return 0;
24 27 }
25 28  
26 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 146 struct image_info *info);
147 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 151 void target_set_brk(abi_ulong new_brk);
152 152 abi_long do_brk(abi_ulong new_brk);
153 153 void syscall_init(void);
... ... @@ -179,9 +179,7 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
179 179 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
180 180 long do_sigreturn(CPUState *env);
181 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 184 #ifdef TARGET_I386
187 185 /* vm86.c */
... ... @@ -207,12 +205,15 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
207 205 /* user access */
208 206  
209 207 #define VERIFY_READ 0
210   -#define VERIFY_WRITE 1
  208 +#define VERIFY_WRITE 1 /* implies read access */
211 209  
212 210 #define access_ok(type,addr,size) \
213 211 (page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0)
214 212  
215 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 217 #define __put_user(x, hptr)\
217 218 ({\
218 219 int size = sizeof(*hptr);\
... ... @@ -257,26 +258,44 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
257 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 299 /* Functions for accessing guest memory. The tget and tput functions
281 300 read/write single values, byteswapping as neccessary. The lock_user
282 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 304  
286 305 /* Lock an area of guest memory into the host. If copy is true then the
287 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 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 321 #else
299 322 return g2h(guest_addr);
300 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 330 long len)
307 331 {
  332 +
308 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 337 return;
311 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 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 348 /* Like lock_user but for null terminated strings. */
324 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 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 362 unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
336 363  
337 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 435 }
436 436  
437 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 441 int ret;
443 442 struct target_sigaltstack oss;
444 443  
445 444 /* XXX: test errors */
446   - if(uoss)
  445 + if(uoss_addr)
447 446 {
448 447 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
449 448 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
450 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 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 459 || __get_user(ss.ss_sp, &uss->ss_sp)
460 460 || __get_user(ss.ss_size, &uss->ss_size)
461 461 || __get_user(ss.ss_flags, &uss->ss_flags))
462 462 goto out;
  463 + unlock_user_struct(uss, uss_addr, 0);
463 464  
464 465 ret = -TARGET_EPERM;
465 466 if (on_sig_stack(sp))
... ... @@ -484,11 +485,10 @@ int do_sigaltstack(const struct target_sigaltstack *uss,
484 485 target_sigaltstack_used.ss_size = ss.ss_size;
485 486 }
486 487  
487   - if (uoss) {
  488 + if (uoss_addr) {
488 489 ret = -TARGET_EFAULT;
489   - if (!access_ok(VERIFY_WRITE, uoss, sizeof(oss)))
  490 + if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
490 491 goto out;
491   - memcpy(uoss, &oss, sizeof(oss));
492 492 }
493 493  
494 494 ret = 0;
... ... @@ -671,6 +671,7 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
671 671 {
672 672 int err = 0;
673 673  
  674 + /* already locked in setup_frame() */
674 675 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
675 676 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
676 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 707 * Determine which stack to use..
707 708 */
708 709  
709   -static inline void *
  710 +static inline abi_ulong
710 711 get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
711 712 {
712 713 unsigned long esp;
... ... @@ -726,19 +727,22 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
726 727 ka->sa.sa_restorer) {
727 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 734 static void setup_frame(int sig, struct emulated_sigaction *ka,
733 735 target_sigset_t *set, CPUX86State *env)
734 736 {
  737 + abi_ulong frame_addr;
735 738 struct sigframe *frame;
736 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 744 goto give_sigsegv;
  745 +
742 746 err |= __put_user((/*current->exec_domain
743 747 && current->exec_domain->signal_invmap
744 748 && sig < 32
... ... @@ -786,24 +790,29 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
786 790 cpu_x86_load_seg(env, R_CS, __USER_CS);
787 791 env->eflags &= ~TF_MASK;
788 792  
  793 + unlock_user_struct(frame, frame_addr, 1);
  794 +
789 795 return;
790 796  
791 797 give_sigsegv:
  798 + unlock_user_struct(frame, frame_addr, 1);
792 799 if (sig == TARGET_SIGSEGV)
793 800 ka->sa._sa_handler = TARGET_SIG_DFL;
794 801 force_sig(TARGET_SIGSEGV /* , current */);
795 802 }
796 803  
  804 +/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
797 805 static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
798 806 target_siginfo_t *info,
799 807 target_sigset_t *set, CPUX86State *env)
800 808 {
  809 + abi_ulong frame_addr;
801 810 struct rt_sigframe *frame;
802 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 816 goto give_sigsegv;
808 817  
809 818 err |= __put_user((/*current->exec_domain
... ... @@ -859,9 +868,12 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
859 868 cpu_x86_load_seg(env, R_CS, __USER_CS);
860 869 env->eflags &= ~TF_MASK;
861 870  
  871 + unlock_user_struct(frame, frame_addr, 1);
  872 +
862 873 return;
863 874  
864 875 give_sigsegv:
  876 + unlock_user_struct(frame, frame_addr, 1);
865 877 if (sig == TARGET_SIGSEGV)
866 878 ka->sa._sa_handler = TARGET_SIG_DFL;
867 879 force_sig(TARGET_SIGSEGV /* , current */);
... ... @@ -918,7 +930,8 @@ badframe:
918 930  
919 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 935 target_sigset_t target_set;
923 936 sigset_t set;
924 937 int eax, i;
... ... @@ -926,6 +939,8 @@ long do_sigreturn(CPUX86State *env)
926 939 #if defined(DEBUG_SIGNAL)
927 940 fprintf(stderr, "do_sigreturn\n");
928 941 #endif
  942 + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
  943 + goto badframe;
929 944 /* set blocked signals */
930 945 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
931 946 goto badframe;
... ... @@ -940,9 +955,11 @@ long do_sigreturn(CPUX86State *env)
940 955 /* restore registers */
941 956 if (restore_sigcontext(env, &frame->sc, &eax))
942 957 goto badframe;
  958 + unlock_user_struct(frame, frame_addr, 0);
943 959 return eax;
944 960  
945 961 badframe:
  962 + unlock_user_struct(frame, frame_addr, 0);
946 963 force_sig(TARGET_SIGSEGV);
947 964 return 0;
948 965 }
... ... @@ -963,7 +980,7 @@ long do_rt_sigreturn(CPUX86State *env)
963 980 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
964 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 984 goto badframe;
968 985  
969 986 return eax;
... ... @@ -1086,7 +1103,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1086 1103 return err;
1087 1104 }
1088 1105  
1089   -static inline void *
  1106 +static inline abi_ulong
1090 1107 get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
1091 1108 {
1092 1109 unsigned long sp = regs->regs[13];
... ... @@ -1099,7 +1116,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
1099 1116 /*
1100 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 1122 static int
... ... @@ -1167,33 +1184,43 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
1167 1184 return 0;
1168 1185 }
1169 1186  
  1187 +/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1170 1188 static void setup_frame(int usig, struct emulated_sigaction *ka,
1171 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 1193 int i, err = 0;
1175 1194  
  1195 + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
  1196 + return;
  1197 +
1176 1198 err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
1177 1199  
1178 1200 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1179 1201 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1180   - return;
  1202 + goto end;
1181 1203 }
1182 1204  
1183 1205 if (err == 0)
1184 1206 err = setup_return(regs, ka, &frame->retcode, frame, usig);
  1207 +
  1208 +end:
  1209 + unlock_user_struct(frame, frame_addr, 1);
1185 1210 // return err;
1186 1211 }
1187 1212  
  1213 +/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1188 1214 static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1189 1215 target_siginfo_t *info,
1190 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 1220 struct target_sigaltstack stack;
1194 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 1224 return /* 1 */;
1198 1225  
1199 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 1234 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1208 1235 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1209 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 1239 err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
1216 1240 env, set->sig[0]);
1217 1241 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1218 1242 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1219   - return;
  1243 + goto end;
1220 1244 }
1221 1245  
1222 1246 if (err == 0)
... ... @@ -1232,6 +1256,9 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1232 1256 env->regs[2] = (abi_ulong)frame->puc;
1233 1257 }
1234 1258  
  1259 +end:
  1260 + unlock_user_struct(frame, frame_addr, 1);
  1261 +
1235 1262 // return err;
1236 1263 }
1237 1264  
... ... @@ -1338,7 +1365,7 @@ long do_rt_sigreturn(CPUState *env)
1338 1365 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1339 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 1369 goto badframe;
1343 1370  
1344 1371 #if 0
... ... @@ -1788,8 +1815,8 @@ void sparc64_set_context(CPUSPARCState *env)
1788 1815 abi_ulong *src, *dst;
1789 1816  
1790 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 1820 if (err || ((pc | npc) & 3))
1794 1821 goto do_sigsegv;
1795 1822 if (env->regwptr[UREG_I1]) {
... ... @@ -1797,14 +1824,14 @@ void sparc64_set_context(CPUSPARCState *env)
1797 1824 sigset_t set;
1798 1825  
1799 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 1828 goto do_sigsegv;
1802 1829 } else {
1803 1830 src = &ucp->uc_sigmask;
1804 1831 dst = &target_set;
1805 1832 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
1806 1833 i++, dst++, src++)
1807   - err |= get_user(dst, src);
  1834 + err |= __get_user(dst, src);
1808 1835 if (err)
1809 1836 goto do_sigsegv;
1810 1837 }
... ... @@ -1813,44 +1840,44 @@ void sparc64_set_context(CPUSPARCState *env)
1813 1840 }
1814 1841 env->pc = pc;
1815 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 1845 env->asi = (tstate >> 24) & 0xff;
1819 1846 PUT_CCR(env, tstate >> 32);
1820 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 1873 src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
1847 1874 dst = &env->fpr;
1848 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 1881 if (err)
1855 1882 goto do_sigsegv;
1856 1883  
... ... @@ -1884,52 +1911,52 @@ void sparc64_get_context(CPUSPARCState *env)
1884 1911 sigprocmask(0, NULL, &set);
1885 1912 host_to_target_sigset_internal(&target_set, &set);
1886 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 1916 else {
1890 1917 src = &target_set;
1891 1918 dst = &ucp->uc_sigmask;
1892 1919 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
1893 1920 i++, dst++, src++)
1894   - err |= put_user(src, dst);
  1921 + err |= __put_user(src, dst);
1895 1922 if (err)
1896 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 1953 src = &env->fpr;
1927 1954 dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
1928 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 1961 if (err)
1935 1962 goto do_sigsegv;
... ... @@ -2191,7 +2218,7 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2191 2218 /*
2192 2219 * Determine which stack to use..
2193 2220 */
2194   -static inline void *
  2221 +static inline abi_ulong
2195 2222 get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
2196 2223 {
2197 2224 unsigned long sp;
... ... @@ -2211,17 +2238,19 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
2211 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 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 2248 struct sigframe *frame;
  2249 + abi_ulong frame_addr;
2221 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 2254 goto give_sigsegv;
2226 2255  
2227 2256 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
... ... @@ -2253,9 +2282,11 @@ static void setup_frame(int sig, struct emulated_sigaction * ka,
2253 2282 * since it returns to userland using eret
2254 2283 * we cannot do this here, and we must set PC directly */
2255 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 2286 return;
2257 2287  
2258 2288 give_sigsegv:
  2289 + unlock_user_struct(frame, frame_addr, 1);
2259 2290 force_sig(TARGET_SIGSEGV/*, current*/);
2260 2291 return;
2261 2292 }
... ... @@ -2263,6 +2294,7 @@ give_sigsegv:
2263 2294 long do_sigreturn(CPUState *regs)
2264 2295 {
2265 2296 struct sigframe *frame;
  2297 + abi_ulong frame_addr;
2266 2298 sigset_t blocked;
2267 2299 target_sigset_t target_set;
2268 2300 int i;
... ... @@ -2270,8 +2302,8 @@ long do_sigreturn(CPUState *regs)
2270 2302 #if defined(DEBUG_SIGNAL)
2271 2303 fprintf(stderr, "do_sigreturn\n");
2272 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 2307 goto badframe;
2276 2308  
2277 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 81  
82 82 gemu_log("[");
83 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 92 return;
88 93  
89   - target_fds = lock_user(target_fds_addr, sizeof(*target_fds)*(n / TARGET_LONG_BITS + 1), 1);
90 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 96 gemu_log("%d,", i );
93 97 }
94 98 unlock_user(target_fds, target_fds_addr, 0);
... ... @@ -102,10 +106,9 @@ print_timeval(target_ulong tv_addr)
102 106 if( tv_addr ) {
103 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 111 return;
107   -
108   - tv = lock_user(tv_addr, sizeof(*tv), 1);
109 112 gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}",
110 113 tv->tv_sec, tv->tv_usec);
111 114 unlock_user(tv, tv_addr, 0);
... ... @@ -165,27 +168,25 @@ print_execve(struct syscallname *name,
165 168 target_ulong arg_ptr_addr;
166 169 char *s;
167 170  
168   - if (!access_ok(VERIFY_READ, arg1, 1))
  171 + if (!(s = lock_user_string(arg1)))
169 172 return;
170   -
171   - s = lock_user_string(arg1);
172 173 gemu_log("%s(\"%s\",{", name->name, s);
173 174 unlock_user(s, arg1, 0);
174 175  
175 176 for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(target_ulong)) {
176 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 181 return;
180   -
181   - arg_ptr = lock_user(arg_ptr_addr, sizeof(target_ulong), 1);
182 182 arg_addr = tswapl(*arg_ptr);
183 183 unlock_user(arg_ptr, arg_ptr_addr, 0);
184 184 if (!arg_addr)
185 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 192 gemu_log("NULL})");
... ...
linux-user/syscall.c
... ... @@ -504,12 +504,13 @@ static inline abi_long host_to_target_clock_t(long ticks)
504 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 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 514 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
514 515 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
515 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 530 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
530 531 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
531 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 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 544 tv->tv_sec = tswapl(target_tv->tv_sec);
541 545 tv->tv_usec = tswapl(target_tv->tv_usec);
542 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 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 558 target_tv->tv_sec = tswapl(tv->tv_sec);
552 559 target_tv->tv_usec = tswapl(tv->tv_usec);
553 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 576 int ok;
568 577  
569 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 584 rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
572 585 } else {
573 586 target_rfds = NULL;
574 587 rfds_ptr = NULL;
575 588 }
576 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 595 wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
579 596 } else {
580 597 target_wfds = NULL;
581 598 wfds_ptr = NULL;
582 599 }
583 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 606 efds_ptr = target_to_host_fds(&efds, target_efds, n);
586 607 } else {
587 608 target_efds = NULL;
... ... @@ -606,38 +627,45 @@ static abi_long do_select(int n,
606 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 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 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 648 memcpy(addr, target_saddr, len);
627 649 addr->sa_family = tswap16(target_saddr->sa_family);
628 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 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 664 memcpy(target_saddr, addr, len);
639 665 target_saddr->sa_family = tswap16(addr->sa_family);
640 666 unlock_user(target_saddr, target_addr, len);
  667 +
  668 + return 0;
641 669 }
642 670  
643 671 /* ??? Should this also swap msgh->name? */
... ... @@ -941,35 +969,56 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
941 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 979 struct target_iovec *target_vec;
948 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 986 for(i = 0;i < count; i++) {
953 987 base = tswapl(target_vec[i].iov_base);
954 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 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 1008 struct target_iovec *target_vec;
964 1009 abi_ulong base;
965 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 1015 for(i = 0;i < count; i++) {
969 1016 base = tswapl(target_vec[i].iov_base);
970 1017 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
971 1018 }
972 1019 unlock_user (target_vec, target_addr, 0);
  1020 +
  1021 + return 0;
973 1022 }
974 1023  
975 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 1082 struct iovec *vec;
1034 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 1091 if (msgp->msg_name) {
1038 1092 msg.msg_namelen = tswap32(msgp->msg_namelen);
1039 1093 msg.msg_name = alloca(msg.msg_namelen);
... ... @@ -1050,7 +1104,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1050 1104 count = tswapl(msgp->msg_iovlen);
1051 1105 vec = alloca(count * sizeof(struct iovec));
1052 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 1108 msg.msg_iovlen = count;
1055 1109 msg.msg_iov = vec;
1056 1110  
... ... @@ -1063,6 +1117,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1063 1117 host_to_target_cmsg(msgp, &msg);
1064 1118 }
1065 1119 unlock_iovec(vec, target_vec, count, !send);
  1120 + unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1066 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 1192 void *host_msg;
1138 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 1198 if (target_addr) {
1142 1199 addr = alloca(addrlen);
1143 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 1216 void *host_msg;
1160 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 1222 if (target_addr) {
1164 1223 addrlen = tget32(target_addrlen);
1165 1224 addr = alloca(addrlen);
... ... @@ -1381,13 +1440,14 @@ struct target_semid_ds
1381 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 1446 struct target_ipc_perm *target_ip;
1388 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 1451 target_ip=&(target_sd->sem_perm);
1392 1452 host_ip->__key = tswapl(target_ip->__key);
1393 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 1456 host_ip->cgid = tswapl(target_ip->cgid);
1397 1457 host_ip->mode = tswapl(target_ip->mode);
1398 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 1465 struct target_ipc_perm *target_ip;
1405 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 1470 target_ip = &(target_sd->sem_perm);
1409 1471 target_ip->__key = tswapl(host_ip->__key);
1410 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 1475 target_ip->cgid = tswapl(host_ip->cgid);
1414 1476 target_ip->mode = tswapl(host_ip->mode);
1415 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 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 1488 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1425 1489 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1426 1490 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1427 1491 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1428 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 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 1503 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1438 1504 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1439 1505 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1440 1506 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1441 1507 unlock_user_struct(target_sd, target_addr, 1);
  1508 + return 0;
1442 1509 }
1443 1510  
1444 1511 union semun {
... ... @@ -1453,67 +1520,75 @@ union target_semun {
1453 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 1528 union target_semun *target_su;
1462 1529  
1463 1530 switch( cmd ) {
1464 1531 case IPC_STAT:
1465 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 1535 target_to_host_semid_ds(ds,target_su->buf);
1468 1536 host_su->buf = ds;
1469 1537 unlock_user_struct(target_su, target_addr, 0);
1470 1538 break;
1471 1539 case GETVAL:
1472 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 1543 host_su->val = tswapl(target_su->val);
1475 1544 unlock_user_struct(target_su, target_addr, 0);
1476 1545 break;
1477 1546 case GETALL:
1478 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 1550 *host_su->array = tswap16(*target_su->array);
1481 1551 unlock_user_struct(target_su, target_addr, 0);
1482 1552 break;
1483 1553 default:
1484 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 1564 union target_semun *target_su;
1494 1565  
1495 1566 switch( cmd ) {
1496 1567 case IPC_STAT:
1497 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 1571 host_to_target_semid_ds(target_su->buf,ds);
1500 1572 unlock_user_struct(target_su, target_addr, 1);
1501 1573 break;
1502 1574 case GETVAL:
1503 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 1578 target_su->val = tswapl(host_su->val);
1506 1579 unlock_user_struct(target_su, target_addr, 1);
1507 1580 break;
1508 1581 case GETALL:
1509 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 1585 *target_su->array = tswap16(*host_su->array);
1512 1586 unlock_user_struct(target_su, target_addr, 1);
1513 1587 break;
1514 1588 default:
1515 1589 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1516 1590 }
  1591 + return 0;
1517 1592 }
1518 1593  
1519 1594 static inline abi_long do_semctl(int first, int second, int third,
... ... @@ -1580,12 +1655,13 @@ struct target_msqid_ds
1580 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 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 1665 target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1590 1666 host_md->msg_stime = tswapl(target_md->msg_stime);
1591 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 1672 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1597 1673 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1598 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 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 1685 host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1608 1686 target_md->msg_stime = tswapl(host_md->msg_stime);
1609 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 1692 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1615 1693 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1616 1694 unlock_user_struct(target_md, target_addr, 1);
  1695 + return 0;
1617 1696 }
1618 1697  
1619 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 1724 struct msgbuf *host_mb;
1646 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 1729 host_mb = malloc(msgsz+sizeof(long));
1650 1730 host_mb->mtype = tswapl(target_mb->mtype);
1651 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 1741 int msgflg)
1662 1742 {
1663 1743 struct target_msgbuf *target_mb;
  1744 + char *target_mtext;
1664 1745 struct msgbuf *host_mb;
1665 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 1750 host_mb = malloc(msgsz+sizeof(long));
1669 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 1759 memcpy(target_mb->mtext, host_mb->mtext, ret);
  1760 + unlock_user(target_mtext, target_mtext_addr, ret);
  1761 + }
1672 1762 target_mb->mtype = tswapl(host_mb->mtype);
1673 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 1768 return ret;
1677 1769 }
1678 1770  
... ... @@ -1693,7 +1785,7 @@ static abi_long do_ipc(unsigned int call, int first,
1693 1785  
1694 1786 switch (call) {
1695 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 1789 break;
1698 1790  
1699 1791 case IPCOP_semget:
... ... @@ -1723,13 +1815,14 @@ static abi_long do_ipc(unsigned int call, int first,
1723 1815  
1724 1816 case IPCOP_msgrcv:
1725 1817 {
  1818 + /* XXX: this code is not correct */
1726 1819 struct ipc_kludge
1727 1820 {
1728 1821 void *__unbounded msgp;
1729 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 1826 struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
1734 1827  
1735 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 1854 break;
1762 1855 }
1763 1856 }
1764   - if (put_user(raddr, (abi_ulong *)third))
  1857 + if (put_user(raddr, third, abi_ulong))
1765 1858 return -TARGET_EFAULT;
1766 1859 ret = 0;
1767 1860 break;
... ... @@ -1883,25 +1976,33 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
1883 1976 case IOC_R:
1884 1977 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1885 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 1982 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
1888 1983 unlock_user(argptr, arg, target_size);
1889 1984 }
1890 1985 break;
1891 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 1990 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
1894 1991 unlock_user(argptr, arg, 0);
1895 1992 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1896 1993 break;
1897 1994 default:
1898 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 1999 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
1901 2000 unlock_user(argptr, arg, 0);
1902 2001 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1903 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 2006 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
1906 2007 unlock_user(argptr, arg, target_size);
1907 2008 }
... ... @@ -2138,8 +2239,10 @@ static int read_ldt(abi_ulong ptr, unsigned long bytecount)
2138 2239 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2139 2240 if (size > bytecount)
2140 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 2246 memcpy(p, ldt_table, size);
2144 2247 unlock_user(p, ptr, size);
2145 2248 return size;
... ... @@ -2158,7 +2261,8 @@ static int write_ldt(CPUX86State *env,
2158 2261  
2159 2262 if (bytecount != sizeof(ldt_info))
2160 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 2266 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2163 2267 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2164 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 2469  
2366 2470 switch(cmd) {
2367 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 2474 fl.l_type = tswap16(target_fl->l_type);
2370 2475 fl.l_whence = tswap16(target_fl->l_whence);
2371 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 2479 unlock_user_struct(target_fl, arg, 0);
2375 2480 ret = fcntl(fd, cmd, &fl);
2376 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 2484 target_fl->l_type = tswap16(fl.l_type);
2379 2485 target_fl->l_whence = tswap16(fl.l_whence);
2380 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 2492  
2387 2493 case TARGET_F_SETLK:
2388 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 2497 fl.l_type = tswap16(target_fl->l_type);
2391 2498 fl.l_whence = tswap16(target_fl->l_whence);
2392 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 2504 break;
2398 2505  
2399 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 2509 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2402 2510 fl64.l_whence = tswap16(target_fl64->l_whence);
2403 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 2514 unlock_user_struct(target_fl64, arg, 0);
2407 2515 ret = fcntl(fd, cmd >> 1, &fl64);
2408 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 2519 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2411 2520 target_fl64->l_whence = tswap16(fl64.l_whence);
2412 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 2526 break;
2418 2527 case TARGET_F_SETLK64:
2419 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 2531 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2422 2532 fl64.l_whence = tswap16(target_fl64->l_whence);
2423 2533 fl64.l_start = tswapl(target_fl64->l_start);
2424 2534 fl64.l_len = tswapl(target_fl64->l_len);
2425 2535 fl64.l_pid = tswap16(target_fl64->l_pid);
2426 2536 unlock_user_struct(target_fl64, arg, 0);
2427   - ret = fcntl(fd, cmd >> 1, &fl64);
  2537 + ret = fcntl(fd, cmd >> 1, &fl64);
2428 2538 break;
2429 2539  
2430 2540 case F_GETFL:
... ... @@ -2577,23 +2687,25 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
2577 2687 }
2578 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 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 2697 host_ts->tv_sec = tswapl(target_ts->tv_sec);
2587 2698 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
2588 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 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 2709 target_ts->tv_sec = tswapl(host_ts->tv_sec);
2598 2710 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
2599 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 2741 break;
2630 2742 case TARGET_NR_read:
2631 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 2746 ret = get_errno(read(arg1, p, arg3));
2634 2747 unlock_user(p, arg2, ret);
2635 2748 break;
2636 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 2752 ret = get_errno(write(arg1, p, arg3));
2639 2753 unlock_user(p, arg2, 0);
2640 2754 break;
2641 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 2760 ret = get_errno(open(path(p),
2644 2761 target_to_host_bitmask(arg2, fcntl_flags_tbl),
2645 2762 arg3));
... ... @@ -2647,21 +2764,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2647 2764 break;
2648 2765 #if defined(TARGET_NR_openat) && defined(__NR_openat)
2649 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 2774 break;
2666 2775 #endif
2667 2776 case TARGET_NR_close:
... ... @@ -2685,7 +2794,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2685 2794 #endif
2686 2795 #ifdef TARGET_NR_creat /* not on alpha */
2687 2796 case TARGET_NR_creat:
2688   - p = lock_user_string(arg1);
  2797 + if (!(p = lock_user_string(arg1)))
  2798 + goto efault;
2689 2799 ret = get_errno(creat(p, arg2));
2690 2800 unlock_user(p, arg1, 0);
2691 2801 break;
... ... @@ -2695,54 +2805,43 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2695 2805 void * p2;
2696 2806 p = lock_user_string(arg1);
2697 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 2812 unlock_user(p2, arg2, 0);
2700 2813 unlock_user(p, arg1, 0);
2701 2814 }
2702 2815 break;
2703 2816 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
2704 2817 case TARGET_NR_linkat:
2705   - if (!arg2 || !arg4) {
2706   - ret = -TARGET_EFAULT;
2707   - goto fail;
2708   - }
2709 2818 {
2710 2819 void * p2 = NULL;
  2820 + if (!arg2 || !arg4)
  2821 + goto efault;
2711 2822 p = lock_user_string(arg2);
2712 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 2825 ret = -TARGET_EFAULT;
2717 2826 else
2718 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 2831 break;
2725 2832 #endif
2726 2833 case TARGET_NR_unlink:
2727   - p = lock_user_string(arg1);
  2834 + if (!(p = lock_user_string(arg1)))
  2835 + goto efault;
2728 2836 ret = get_errno(unlink(p));
2729 2837 unlock_user(p, arg1, 0);
2730 2838 break;
2731 2839 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
2732 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 2845 #endif
2747 2846 case TARGET_NR_execve:
2748 2847 {
... ... @@ -2771,7 +2870,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2771 2870 addr = tgetl(gp);
2772 2871 if (!addr)
2773 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 2878 *q = NULL;
2777 2879  
... ... @@ -2780,14 +2882,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2780 2882 addr = tgetl(gp);
2781 2883 if (!addr)
2782 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 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 2896 ret = get_errno(execve(p, argp, envp));
2789 2897 unlock_user(p, arg1, 0);
2790 2898  
  2899 + execve_fail:
2791 2900 for (gp = guest_argp, q = argp; *q;
2792 2901 gp += sizeof(abi_ulong), q++) {
2793 2902 addr = tgetl(gp);
... ... @@ -2801,7 +2910,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2801 2910 }
2802 2911 break;
2803 2912 case TARGET_NR_chdir:
2804   - p = lock_user_string(arg1);
  2913 + if (!(p = lock_user_string(arg1)))
  2914 + goto efault;
2805 2915 ret = get_errno(chdir(p));
2806 2916 unlock_user(p, arg1, 0);
2807 2917 break;
... ... @@ -2816,28 +2926,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2816 2926 break;
2817 2927 #endif
2818 2928 case TARGET_NR_mknod:
2819   - p = lock_user_string(arg1);
  2929 + if (!(p = lock_user_string(arg1)))
  2930 + goto efault;
2820 2931 ret = get_errno(mknod(p, arg2, arg3));
2821 2932 unlock_user(p, arg1, 0);
2822 2933 break;
2823 2934 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
2824 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 2940 break;
2838 2941 #endif
2839 2942 case TARGET_NR_chmod:
2840   - p = lock_user_string(arg1);
  2943 + if (!(p = lock_user_string(arg1)))
  2944 + goto efault;
2841 2945 ret = get_errno(chmod(p, arg2));
2842 2946 unlock_user(p, arg1, 0);
2843 2947 break;
... ... @@ -2866,15 +2970,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2866 2970 p = lock_user_string(arg1);
2867 2971 p2 = lock_user_string(arg2);
2868 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 2984 break;
2874 2985 }
2875 2986 #ifdef TARGET_NR_umount
2876 2987 case TARGET_NR_umount:
2877   - p = lock_user_string(arg1);
  2988 + if (!(p = lock_user_string(arg1)))
  2989 + goto efault;
2878 2990 ret = get_errno(umount(p));
2879 2991 unlock_user(p, arg1, 0);
2880 2992 break;
... ... @@ -2910,7 +3022,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
2910 3022 struct utimbuf tbuf, *host_tbuf;
2911 3023 struct target_utimbuf *target_tbuf;
2912 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 3027 tbuf.actime = tswapl(target_tbuf->actime);
2915 3028 tbuf.modtime = tswapl(target_tbuf->modtime);
2916 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 3031 } else {
2919 3032 host_tbuf = NULL;
2920 3033 }
2921   - p = lock_user_string(arg1);
  3034 + if (!(p = lock_user_string(arg1)))
  3035 + goto efault;
2922 3036 ret = get_errno(utime(p, host_tbuf));
2923 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 3049 } else {
2936 3050 tvp = NULL;
2937 3051 }
2938   - p = lock_user_string(arg1);
  3052 + if (!(p = lock_user_string(arg1)))
  3053 + goto efault;
2939 3054 ret = get_errno(utimes(p, tvp));
2940 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 3064 goto unimplemented;
2950 3065 #endif
2951 3066 case TARGET_NR_access:
2952   - p = lock_user_string(arg1);
  3067 + if (!(p = lock_user_string(arg1)))
  3068 + goto efault;
2953 3069 ret = get_errno(access(p, arg2));
2954 3070 unlock_user(p, arg1, 0);
2955 3071 break;
2956 3072 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
2957 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 3078 break;
2971 3079 #endif
2972 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 3098 void *p2;
2991 3099 p = lock_user_string(arg1);
2992 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 3105 unlock_user(p2, arg2, 0);
2995 3106 unlock_user(p, arg1, 0);
2996 3107 }
2997 3108 break;
2998 3109 #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
2999 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 3113 p = lock_user_string(arg2);
3007 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 3116 ret = -TARGET_EFAULT;
3012 3117 else
3013 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 3122 break;
3020 3123 #endif
3021 3124 case TARGET_NR_mkdir:
3022   - p = lock_user_string(arg1);
  3125 + if (!(p = lock_user_string(arg1)))
  3126 + goto efault;
3023 3127 ret = get_errno(mkdir(p, arg2));
3024 3128 unlock_user(p, arg1, 0);
3025 3129 break;
3026 3130 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3027 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 3136 break;
3041 3137 #endif
3042 3138 case TARGET_NR_rmdir:
3043   - p = lock_user_string(arg1);
  3139 + if (!(p = lock_user_string(arg1)))
  3140 + goto efault;
3044 3141 ret = get_errno(rmdir(p));
3045 3142 unlock_user(p, arg1, 0);
3046 3143 break;
... ... @@ -3069,7 +3166,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3069 3166 struct tms tms;
3070 3167 ret = get_errno(times(&tms));
3071 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 3172 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3074 3173 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3075 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 3187 goto unimplemented;
3089 3188 #endif
3090 3189 case TARGET_NR_acct:
3091   - p = lock_user_string(arg1);
  3190 + if (!(p = lock_user_string(arg1)))
  3191 + goto efault;
3092 3192 ret = get_errno(acct(path(p)));
3093 3193 unlock_user(p, arg1, 0);
3094 3194 break;
3095 3195 #ifdef TARGET_NR_umount2 /* not on alpha */
3096 3196 case TARGET_NR_umount2:
3097   - p = lock_user_string(arg1);
  3197 + if (!(p = lock_user_string(arg1)))
  3198 + goto efault;
3098 3199 ret = get_errno(umount2(p, arg2));
3099 3200 unlock_user(p, arg1, 0);
3100 3201 break;
... ... @@ -3128,7 +3229,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3128 3229 ret = get_errno(umask(arg1));
3129 3230 break;
3130 3231 case TARGET_NR_chroot:
3131   - p = lock_user_string(arg1);
  3232 + if (!(p = lock_user_string(arg1)))
  3233 + goto efault;
3132 3234 ret = get_errno(chroot(p));
3133 3235 unlock_user(p, arg1, 0);
3134 3236 break;
... ... @@ -3155,7 +3257,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3155 3257 struct target_old_sigaction *old_act;
3156 3258 struct target_sigaction act, oact, *pact;
3157 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 3262 act._sa_handler = old_act->_sa_handler;
3160 3263 target_siginitset(&act.sa_mask, old_act->sa_mask);
3161 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 3270 }
3168 3271 ret = get_errno(do_sigaction(arg1, pact, &oact));
3169 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 3275 old_act->_sa_handler = oact._sa_handler;
3172 3276 old_act->sa_mask = oact.sa_mask.sig[0];
3173 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 3282 struct target_sigaction act, oact, *pact, *old_act;
3179 3283  
3180 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 3287 act._sa_handler = old_act->_sa_handler;
3183 3288 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3184 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 3296 ret = get_errno(do_sigaction(arg1, pact, &oact));
3192 3297  
3193 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 3301 old_act->_sa_handler = oact._sa_handler;
3196 3302 old_act->sa_flags = oact.sa_flags;
3197 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 3315 struct target_sigaction *act;
3210 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 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 3329 oact = NULL;
3220 3330 ret = get_errno(do_sigaction(arg1, act, oact));
3221   - if (arg2)
  3331 + rt_sigaction_fail:
  3332 + if (act)
3222 3333 unlock_user_struct(act, arg2, 0);
3223   - if (arg3)
  3334 + if (oact)
3224 3335 unlock_user_struct(oact, arg3, 1);
3225 3336 }
3226 3337 break;
... ... @@ -3270,7 +3381,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3270 3381 ret = -TARGET_EINVAL;
3271 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 3386 target_to_host_old_sigset(&set, p);
3275 3387 unlock_user(p, arg2, 0);
3276 3388 set_ptr = &set;
... ... @@ -3280,7 +3392,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3280 3392 }
3281 3393 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3282 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 3397 host_to_target_old_sigset(p, &oldset);
3285 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 3420 ret = -TARGET_EINVAL;
3308 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 3425 target_to_host_sigset(&set, p);
3312 3426 unlock_user(p, arg2, 0);
3313 3427 set_ptr = &set;
... ... @@ -3317,7 +3431,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3317 3431 }
3318 3432 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
3319 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 3436 host_to_target_sigset(p, &oldset);
3322 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 3444 sigset_t set;
3330 3445 ret = get_errno(sigpending(&set));
3331 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 3449 host_to_target_old_sigset(p, &set);
3334 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 3457 sigset_t set;
3342 3458 ret = get_errno(sigpending(&set));
3343 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 3462 host_to_target_sigset(p, &set);
3346 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 3468 case TARGET_NR_sigsuspend:
3352 3469 {
3353 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 3473 target_to_host_old_sigset(&set, p);
3356 3474 unlock_user(p, arg1, 0);
3357 3475 ret = get_errno(sigsuspend(&set));
... ... @@ -3361,7 +3479,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3361 3479 case TARGET_NR_rt_sigsuspend:
3362 3480 {
3363 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 3484 target_to_host_sigset(&set, p);
3366 3485 unlock_user(p, arg1, 0);
3367 3486 ret = get_errno(sigsuspend(&set));
... ... @@ -3373,7 +3492,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3373 3492 struct timespec uts, *puts;
3374 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 3497 target_to_host_sigset(&set, p);
3378 3498 unlock_user(p, arg1, 0);
3379 3499 if (arg3) {
... ... @@ -3384,7 +3504,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3384 3504 }
3385 3505 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
3386 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 3509 host_to_target_siginfo(p, &uinfo);
3389 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 3514 case TARGET_NR_rt_sigqueueinfo:
3394 3515 {
3395 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 3519 target_to_host_siginfo(&uinfo, p);
3398 3520 unlock_user(p, arg1, 0);
3399 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 3532 ret = do_rt_sigreturn(cpu_env);
3411 3533 break;
3412 3534 case TARGET_NR_sethostname:
3413   - p = lock_user_string(arg1);
  3535 + if (!(p = lock_user_string(arg1)))
  3536 + goto efault;
3414 3537 ret = get_errno(sethostname(p, arg2));
3415 3538 unlock_user(p, arg1, 0);
3416 3539 break;
... ... @@ -3420,7 +3543,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3420 3543 int resource = arg1;
3421 3544 struct target_rlimit *target_rlim;
3422 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 3548 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3425 3549 rlim.rlim_max = tswapl(target_rlim->rlim_max);
3426 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 3560  
3437 3561 ret = get_errno(getrlimit(resource, &rlim));
3438 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 3565 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3441 3566 rlim.rlim_max = tswapl(target_rlim->rlim_max);
3442 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 3600 abi_ulong inp, outp, exp, tvp;
3476 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 3605 nsel = tswapl(sel->n);
3480 3606 inp = tswapl(sel->inp);
3481 3607 outp = tswapl(sel->outp);
... ... @@ -3491,31 +3617,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3491 3617 void *p2;
3492 3618 p = lock_user_string(arg1);
3493 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 3624 unlock_user(p2, arg2, 0);
3496 3625 unlock_user(p, arg1, 0);
3497 3626 }
3498 3627 break;
3499 3628 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
3500 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 3632 p = lock_user_string(arg1);
3508 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 3635 ret = -TARGET_EFAULT;
3513 3636 else
3514 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 3641 break;
3521 3642 #endif
... ... @@ -3527,32 +3648,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3527 3648 {
3528 3649 void *p2;
3529 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 3656 unlock_user(p2, arg2, ret);
3533 3657 unlock_user(p, arg1, 0);
3534 3658 }
3535 3659 break;
3536 3660 #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
3537 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 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 3667 ret = -TARGET_EFAULT;
3550 3668 else
3551 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 3673 break;
3558 3674 #endif
... ... @@ -3562,7 +3678,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3562 3678 #endif
3563 3679 #ifdef TARGET_NR_swapon
3564 3680 case TARGET_NR_swapon:
3565   - p = lock_user_string(arg1);
  3681 + if (!(p = lock_user_string(arg1)))
  3682 + goto efault;
3566 3683 ret = get_errno(swapon(p, arg2));
3567 3684 unlock_user(p, arg1, 0);
3568 3685 break;
... ... @@ -3579,7 +3696,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3579 3696 {
3580 3697 abi_ulong *v;
3581 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 3701 v1 = tswapl(v[0]);
3584 3702 v2 = tswapl(v[1]);
3585 3703 v3 = tswapl(v[2]);
... ... @@ -3650,7 +3768,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3650 3768 break;
3651 3769 #endif
3652 3770 case TARGET_NR_truncate:
3653   - p = lock_user_string(arg1);
  3771 + if (!(p = lock_user_string(arg1)))
  3772 + goto efault;
3654 3773 ret = get_errno(truncate(p, arg2));
3655 3774 unlock_user(p, arg1, 0);
3656 3775 break;
... ... @@ -3662,18 +3781,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3662 3781 break;
3663 3782 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
3664 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 3788 break;
3678 3789 #endif
3679 3790 case TARGET_NR_getpriority:
... ... @@ -3690,25 +3801,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3690 3801 goto unimplemented;
3691 3802 #endif
3692 3803 case TARGET_NR_statfs:
3693   - p = lock_user_string(arg1);
  3804 + if (!(p = lock_user_string(arg1)))
  3805 + goto efault;
3694 3806 ret = get_errno(statfs(path(p), &stfs));
3695 3807 unlock_user(p, arg1, 0);
3696 3808 convert_statfs:
3697 3809 if (!is_error(ret)) {
3698 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 3824 unlock_user_struct(target_stfs, arg2, 1);
3713 3825 }
3714 3826 break;
... ... @@ -3717,26 +3829,27 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3717 3829 goto convert_statfs;
3718 3830 #ifdef TARGET_NR_statfs64
3719 3831 case TARGET_NR_statfs64:
3720   - p = lock_user_string(arg1);
  3832 + if (!(p = lock_user_string(arg1)))
  3833 + goto efault;
3721 3834 ret = get_errno(statfs(path(p), &stfs));
3722 3835 unlock_user(p, arg1, 0);
3723 3836 convert_statfs64:
3724 3837 if (!is_error(ret)) {
3725 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 3854 break;
3742 3855 case TARGET_NR_fstatfs64:
... ... @@ -3839,7 +3952,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3839 3952 #endif
3840 3953  
3841 3954 case TARGET_NR_syslog:
3842   - p = lock_user_string(arg2);
  3955 + if (!(p = lock_user_string(arg2)))
  3956 + goto efault;
3843 3957 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
3844 3958 unlock_user(p, arg2, 0);
3845 3959 break;
... ... @@ -3880,12 +3994,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3880 3994 }
3881 3995 break;
3882 3996 case TARGET_NR_stat:
3883   - p = lock_user_string(arg1);
  3997 + if (!(p = lock_user_string(arg1)))
  3998 + goto efault;
3884 3999 ret = get_errno(stat(path(p), &st));
3885 4000 unlock_user(p, arg1, 0);
3886 4001 goto do_stat;
3887 4002 case TARGET_NR_lstat:
3888   - p = lock_user_string(arg1);
  4003 + if (!(p = lock_user_string(arg1)))
  4004 + goto efault;
3889 4005 ret = get_errno(lstat(path(p), &st));
3890 4006 unlock_user(p, arg1, 0);
3891 4007 goto do_stat;
... ... @@ -3896,7 +4012,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3896 4012 if (!is_error(ret)) {
3897 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 4017 #if defined(TARGET_MIPS) || (defined(TARGET_SPARC64) && !defined(TARGET_ABI32))
3901 4018 target_st->st_dev = tswap32(st.st_dev);
3902 4019 #else
... ... @@ -3979,7 +4096,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3979 4096 break;
3980 4097 #ifdef TARGET_NR_swapoff
3981 4098 case TARGET_NR_swapoff:
3982   - p = lock_user_string(arg1);
  4099 + if (!(p = lock_user_string(arg1)))
  4100 + goto efault;
3983 4101 ret = get_errno(swapoff(p));
3984 4102 unlock_user(p, arg1, 0);
3985 4103 break;
... ... @@ -3991,8 +4109,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3991 4109 ret = get_errno(sysinfo(&value));
3992 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 4114 __put_user(value.uptime, &target_value->uptime);
3997 4115 __put_user(value.loads[0], &target_value->loads[0]);
3998 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 4148 break;
4031 4149 #endif
4032 4150 case TARGET_NR_setdomainname:
4033   - p = lock_user_string(arg1);
  4151 + if (!(p = lock_user_string(arg1)))
  4152 + goto efault;
4034 4153 ret = get_errno(setdomainname(p, arg2));
4035 4154 unlock_user(p, arg1, 0);
4036 4155 break;
... ... @@ -4039,7 +4158,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4039 4158 {
4040 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 4163 ret = get_errno(sys_uname(buf));
4044 4164 if (!is_error(ret)) {
4045 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 4244  
4125 4245 dirp = malloc(count);
4126 4246 if (!dirp) {
4127   - ret = -TARGET_EFAULT;
  4247 + ret = -TARGET_ENOMEM;
4128 4248 goto fail;
4129 4249 }
4130 4250  
... ... @@ -4138,7 +4258,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4138 4258  
4139 4259 count1 = 0;
4140 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 4263 tde = target_dirp;
4143 4264 while (len > 0) {
4144 4265 reclen = de->d_reclen;
... ... @@ -4157,8 +4278,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4157 4278 count1 += treclen;
4158 4279 }
4159 4280 ret = count1;
  4281 + unlock_user(target_dirp, arg2, ret);
4160 4282 }
4161   - unlock_user(target_dirp, arg2, ret);
4162 4283 free(dirp);
4163 4284 }
4164 4285 #else
... ... @@ -4166,7 +4287,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4166 4287 struct dirent *dirp;
4167 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 4292 ret = get_errno(sys_getdents(arg1, dirp, count));
4171 4293 if (!is_error(ret)) {
4172 4294 struct dirent *de;
... ... @@ -4193,7 +4315,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4193 4315 {
4194 4316 struct dirent64 *dirp;
4195 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 4320 ret = get_errno(sys_getdents64(arg1, dirp, count));
4198 4321 if (!is_error(ret)) {
4199 4322 struct dirent64 *de;
... ... @@ -4229,7 +4352,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4229 4352 struct pollfd *pfd;
4230 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 4358 pfd = alloca(sizeof(struct pollfd) * nfds);
4234 4359 for(i = 0; i < nfds; i++) {
4235 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 4383 struct iovec *vec;
4259 4384  
4260 4385 vec = alloca(count * sizeof(struct iovec));
4261   - lock_iovec(vec, arg2, count, 0);
  4386 + lock_iovec(VERIFY_WRITE, vec, arg2, count, 0);
4262 4387 ret = get_errno(readv(arg1, vec, count));
4263 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 4394 struct iovec *vec;
4270 4395  
4271 4396 vec = alloca(count * sizeof(struct iovec));
4272   - lock_iovec(vec, arg2, count, 1);
  4397 + lock_iovec(VERIFY_READ, vec, arg2, count, 1);
4273 4398 ret = get_errno(writev(arg1, vec, count));
4274 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 4417 struct sched_param *target_schp;
4293 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 4422 schp.sched_priority = tswap32(target_schp->sched_priority);
4297 4423 unlock_user_struct(target_schp, arg2, 0);
4298 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 4430 struct sched_param schp;
4305 4431 ret = get_errno(sched_getparam(arg1, &schp));
4306 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 4435 target_schp->sched_priority = tswap32(schp.sched_priority);
4309 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 4441 {
4315 4442 struct sched_param *target_schp;
4316 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 4446 schp.sched_priority = tswap32(target_schp->sched_priority);
4319 4447 unlock_user_struct(target_schp, arg3, 0);
4320 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 4506 #ifdef TARGET_NR_pread
4379 4507 case TARGET_NR_pread:
4380 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 4511 ret = get_errno(pread(arg1, p, arg3, arg4));
4383 4512 unlock_user(p, arg2, ret);
4384 4513 break;
4385 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 4517 ret = get_errno(pwrite(arg1, p, arg3, arg4));
4388 4518 unlock_user(p, arg2, 0);
4389 4519 break;
4390 4520 #endif
4391 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 4524 ret = get_errno(sys_getcwd1(p, arg2));
4394 4525 unlock_user(p, arg1, ret);
4395 4526 break;
... ... @@ -4400,9 +4531,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4400 4531 case TARGET_NR_sigaltstack:
4401 4532 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
4402 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 4535 break;
4407 4536 #else
4408 4537 goto unimplemented;
... ... @@ -4429,7 +4558,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4429 4558 ret = get_errno(getrlimit(arg1, &rlim));
4430 4559 if (!is_error(ret)) {
4431 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 4563 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
4434 4564 target_rlim->rlim_max = tswapl(rlim.rlim_max);
4435 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 4569 #endif
4440 4570 #ifdef TARGET_NR_truncate64
4441 4571 case TARGET_NR_truncate64:
4442   - p = lock_user_string(arg1);
  4572 + if (!(p = lock_user_string(arg1)))
  4573 + goto efault;
4443 4574 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
4444 4575 unlock_user(p, arg1, 0);
4445 4576 break;
... ... @@ -4451,14 +4582,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4451 4582 #endif
4452 4583 #ifdef TARGET_NR_stat64
4453 4584 case TARGET_NR_stat64:
4454   - p = lock_user_string(arg1);
  4585 + if (!(p = lock_user_string(arg1)))
  4586 + goto efault;
4455 4587 ret = get_errno(stat(path(p), &st));
4456 4588 unlock_user(p, arg1, 0);
4457 4589 goto do_stat64;
4458 4590 #endif
4459 4591 #ifdef TARGET_NR_lstat64
4460 4592 case TARGET_NR_lstat64:
4461   - p = lock_user_string(arg1);
  4593 + if (!(p = lock_user_string(arg1)))
  4594 + goto efault;
4462 4595 ret = get_errno(lstat(path(p), &st));
4463 4596 unlock_user(p, arg1, 0);
4464 4597 goto do_stat64;
... ... @@ -4472,52 +4605,53 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4472 4605 #ifdef TARGET_ARM
4473 4606 if (((CPUARMState *)cpu_env)->eabi) {
4474 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 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 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 4629 } else
4497 4630 #endif
4498 4631 {
4499 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 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 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 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 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 4659 #endif
4526 4660 #ifdef USE_UID16
4527 4661 case TARGET_NR_lchown:
4528   - p = lock_user_string(arg1);
  4662 + if (!(p = lock_user_string(arg1)))
  4663 + goto efault;
4529 4664 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
4530 4665 unlock_user(p, arg1, 0);
4531 4666 break;
... ... @@ -4557,7 +4692,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4557 4692 grouplist = alloca(gidsetsize * sizeof(gid_t));
4558 4693 ret = get_errno(getgroups(gidsetsize, grouplist));
4559 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 4698 for(i = 0;i < gidsetsize; i++)
4562 4699 target_grouplist[i] = tswap16(grouplist[i]);
4563 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 4709 int i;
4573 4710  
4574 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 4717 for(i = 0;i < gidsetsize; i++)
4577 4718 grouplist[i] = tswap16(target_grouplist[i]);
4578 4719 unlock_user(target_grouplist, arg2, 0);
... ... @@ -4584,18 +4725,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4584 4725 break;
4585 4726 #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
4586 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 4732 break;
4600 4733 #endif
4601 4734 #ifdef TARGET_NR_setresuid
... ... @@ -4639,7 +4772,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4639 4772 break;
4640 4773 #endif
4641 4774 case TARGET_NR_chown:
4642   - p = lock_user_string(arg1);
  4775 + if (!(p = lock_user_string(arg1)))
  4776 + goto efault;
4643 4777 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
4644 4778 unlock_user(p, arg1, 0);
4645 4779 break;
... ... @@ -4659,7 +4793,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4659 4793  
4660 4794 #ifdef TARGET_NR_lchown32
4661 4795 case TARGET_NR_lchown32:
4662   - p = lock_user_string(arg1);
  4796 + if (!(p = lock_user_string(arg1)))
  4797 + goto efault;
4663 4798 ret = get_errno(lchown(p, arg2, arg3));
4664 4799 unlock_user(p, arg1, 0);
4665 4800 break;
... ... @@ -4705,7 +4840,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4705 4840 grouplist = alloca(gidsetsize * sizeof(gid_t));
4706 4841 ret = get_errno(getgroups(gidsetsize, grouplist));
4707 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 4848 for(i = 0;i < gidsetsize; i++)
4710 4849 target_grouplist[i] = tswap32(grouplist[i]);
4711 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 4861 int i;
4723 4862  
4724 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 4869 for(i = 0;i < gidsetsize; i++)
4727 4870 grouplist[i] = tswap32(target_grouplist[i]);
4728 4871 unlock_user(target_grouplist, arg2, 0);
... ... @@ -4773,7 +4916,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4773 4916 #endif
4774 4917 #ifdef TARGET_NR_chown32
4775 4918 case TARGET_NR_chown32:
4776   - p = lock_user_string(arg1);
  4919 + if (!(p = lock_user_string(arg1)))
  4920 + goto efault;
4777 4921 ret = get_errno(chown(p, arg2, arg3));
4778 4922 unlock_user(p, arg1, 0);
4779 4923 break;
... ... @@ -4843,7 +4987,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4843 4987 case TARGET_F_GETLK64:
4844 4988 #ifdef TARGET_ARM
4845 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 4994 fl.l_type = tswap16(target_efl->l_type);
4848 4995 fl.l_whence = tswap16(target_efl->l_whence);
4849 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 5000 } else
4854 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 5007 fl.l_type = tswap16(target_fl->l_type);
4858 5008 fl.l_whence = tswap16(target_fl->l_whence);
4859 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 5015 if (ret == 0) {
4866 5016 #ifdef TARGET_ARM
4867 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 5022 target_efl->l_type = tswap16(fl.l_type);
4870 5023 target_efl->l_whence = tswap16(fl.l_whence);
4871 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 5028 } else
4876 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 5035 target_fl->l_type = tswap16(fl.l_type);
4880 5036 target_fl->l_whence = tswap16(fl.l_whence);
4881 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 5046 case TARGET_F_SETLKW64:
4891 5047 #ifdef TARGET_ARM
4892 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 5053 fl.l_type = tswap16(target_efl->l_type);
4895 5054 fl.l_whence = tswap16(target_efl->l_whence);
4896 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 5059 } else
4901 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 5066 fl.l_type = tswap16(target_fl->l_type);
4905 5067 fl.l_whence = tswap16(target_fl->l_whence);
4906 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 5160  
4999 5161 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5000 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 5165 #endif
5004 5166  
5005 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 5190 if (!arg2)
5029 5191 ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5030 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 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 5201 break;
... ... @@ -5050,11 +5210,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5050 5210 ret = -TARGET_ENOSYS;
5051 5211 break;
5052 5212 }
5053   - fail:
  5213 +fail:
5054 5214 #ifdef DEBUG
5055 5215 gemu_log(" = %ld\n", ret);
5056 5216 #endif
5057 5217 if(do_strace)
5058 5218 print_syscall_ret(num, ret);
5059 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 64 TaskState *ts = env->opaque;
65 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 70 /* put the VM86 registers in the userspace register structure */
69 71 target_v86->regs.eax = tswap32(env->regs[R_EAX]);
70 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 426 ts->vm86_saved_regs.gs = env->segs[R_GS].selector;
425 427  
426 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 431 /* build vm86 CPU state */
429 432 ts->v86flags = tswap32(target_v86->regs.eflags);
430 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 107 {
108 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 113 p->gdb_st_dev = cpu_to_be32(s->st_dev);
112 114 p->gdb_st_ino = cpu_to_be32(s->st_ino);
113 115 p->gdb_st_mode = cpu_to_be32(s->st_mode);
... ... @@ -168,9 +170,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
168 170 ARG(2), ARG(3));
169 171 return;
170 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 181 break;
176 182 case HOSTED_CLOSE:
... ... @@ -196,9 +202,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
196 202 ARG(0), ARG(1), len);
197 203 return;
198 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 213 break;
204 214 case HOSTED_WRITE:
... ... @@ -208,9 +218,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
208 218 ARG(0), ARG(1), len);
209 219 return;
210 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 229 break;
216 230 case HOSTED_LSEEK:
... ... @@ -237,7 +251,12 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
237 251 } else {
238 252 p = lock_user_string(ARG(0));
239 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 260 unlock_user(p, ARG(0), 0);
242 261 unlock_user(q, ARG(2), 0);
243 262 }
... ... @@ -248,9 +267,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
248 267 ARG(0), (int)ARG(1));
249 268 return;
250 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 278 break;
256 279 case HOSTED_STAT:
... ... @@ -260,9 +283,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
260 283 return;
261 284 } else {
262 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 293 if (result == 0) {
267 294 translate_stat(env, ARG(2), &s);
268 295 }
... ... @@ -291,10 +318,15 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
291 318 struct gdb_timeval *p;
292 319 result = qemu_gettimeofday(&tv);
293 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 332 break;
... ... @@ -312,9 +344,13 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
312 344 ARG(0), (int)ARG(1));
313 345 return;
314 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 355 break;
320 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 41 cpu_memory_rw_debug(env, addr, p, len, 0);
42 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 45 static char *softmmu_lock_user_string(CPUState *env, uint32_t addr)
46 46 {
47 47 char *p;
... ...