Index: qemu/linux-user/elfload.c =================================================================== --- qemu.orig/linux-user/elfload.c 2007-11-14 09:19:09.000000000 -0700 +++ qemu/linux-user/elfload.c 2007-11-14 11:23:00.000000000 -0700 @@ -179,8 +179,9 @@ regs->ARM_cpsr |= CPSR_T; regs->ARM_pc = infop->entry & 0xfffffffe; regs->ARM_sp = infop->start_stack; - regs->ARM_r2 = tgetl(stack + 8); /* envp */ - regs->ARM_r1 = tgetl(stack + 4); /* envp */ + /* FIXME - what to for failure of get_user()? */ + get_user(regs->ARM_r2, stack + 8, abi_long); /* envp */ + get_user(regs->ARM_r1, stack + 4, abi_long); /* envp */ /* XXX: it seems that r0 is zeroed after ! */ regs->ARM_r0 = 0; /* For uClinux PIC binaries. */ @@ -341,7 +342,8 @@ * but this is what the ABI wants and is needed to allow * execution of PPC BSD programs. */ - _regs->gpr[3] = tgetl(pos); + /* FIXME - what to for failure of get_user()? */ + get_user(_regs->gpr[3], pos, abi_long); pos += sizeof(abi_ulong); _regs->gpr[4] = pos; for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong)) @@ -733,7 +735,8 @@ if (nbyte) { nbyte = qemu_host_page_size - nbyte; do { - tput8(elf_bss, 0); + /* FIXME - what to do if put_user() fails? */ + put_user(0, elf_bss, uint8_t); elf_bss++; } while (--nbyte); } @@ -782,17 +785,11 @@ /* This is correct because Linux defines * elf_addr_t as Elf32_Off / Elf64_Off */ -#if ELF_CLASS == ELFCLASS32 -#define NEW_AUX_ENT(id, val) do { \ - sp -= n; tput32(sp, val); \ - sp -= n; tput32(sp, id); \ +#define NEW_AUX_ENT(id, val) do { \ + sp -= n; put_user(val, sp, abi_ulong); \ + sp -= n; put_user(id, sp, abi_ulong); \ } while(0) -#else -#define NEW_AUX_ENT(id, val) do { \ - sp -= n; tput64(sp, val); \ - sp -= n; tput64(sp, id); \ - } while(0) -#endif + NEW_AUX_ENT (AT_NULL, 0); /* There must be exactly DLINFO_ITEMS entries here. */ Index: qemu/linux-user/flatload.c =================================================================== --- qemu.orig/linux-user/flatload.c 2007-11-14 09:19:09.000000000 -0700 +++ qemu/linux-user/flatload.c 2007-11-14 11:23:00.000000000 -0700 @@ -598,14 +598,16 @@ rp = datapos; while (1) { abi_ulong addr; - addr = tgetl(rp); + if (get_user(addr, rp, abi_ulong)) + return -EFAULT; if (addr == -1) break; if (addr) { addr = calc_reloc(addr, libinfo, id, 0); if (addr == RELOC_FAILED) return -ENOEXEC; - tputl(rp, addr); + if (put_user(addr, rp, abi_ulong)) + return -EFAULT; } rp += sizeof(abi_ulong); } @@ -629,14 +631,16 @@ /* Get the address of the pointer to be relocated (of course, the address has to be relocated first). */ - relval = tgetl(reloc + i * sizeof (abi_ulong)); + if (get_user(relval, reloc + i * sizeof(abi_ulong), abi_ulong)) + return -EFAULT; addr = flat_get_relocate_addr(relval); rp = calc_reloc(addr, libinfo, id, 1); if (rp == RELOC_FAILED) return -ENOEXEC; /* Get the pointer's value. */ - addr = tgetl(rp); + if (get_user(addr, rp, abi_ulong)) + return -EFAULT; if (addr != 0) { /* * Do the relocation. PIC relocs in the data section are @@ -652,13 +656,15 @@ return -ENOEXEC; /* Write back the relocated pointer. */ - tputl(rp, addr); + if (put_user(addr, rp, abi_ulong)) + return -EFAULT; } } } else { for (i = 0; i < relocs; i++) { abi_ulong relval; - relval = tgetl(reloc + i * sizeof (abi_ulong)); + if (get_user(relval, reloc + i * sizeof(abi_ulong), abi_ulong)) + return -EFAULT; old_reloc(&libinfo[0], relval); } } @@ -744,9 +750,13 @@ p = libinfo[i].start_data; for (j=0; j0; i--) { if (libinfo[i].loaded) { /* Push previos first to call address */ - --sp; put_user(start_addr, sp); + --sp; + if (put_user(start_addr, sp, abi_ulong)) + return -EFAULT; start_addr = libinfo[i].entry; } } Index: qemu/linux-user/main.c =================================================================== --- qemu.orig/linux-user/main.c 2007-11-14 09:19:09.000000000 -0700 +++ qemu/linux-user/main.c 2007-11-14 11:23:00.000000000 -0700 @@ -342,7 +342,8 @@ /* we handle the FPU emulation here, as Linux */ /* we get the opcode */ - opcode = tget32(env->regs[15]); + /* FIXME - what to do if get_user() fails? */ + get_user(opcode, env->regs[15], uint32_t); if (EmulateAll(opcode, &ts->fpa, env) == 0) { info.si_signo = SIGILL; @@ -363,20 +364,24 @@ /* system call */ if (trapnr == EXCP_BKPT) { if (env->thumb) { - insn = tget16(env->regs[15]); + /* FIXME - what to do if get_user() fails? */ + get_user(insn, env->regs[15], uint16_t); n = insn & 0xff; env->regs[15] += 2; } else { - insn = tget32(env->regs[15]); + /* FIXME - what to do if get_user() fails? */ + get_user(insn, env->regs[15], uint32_t); n = (insn & 0xf) | ((insn >> 4) & 0xff0); env->regs[15] += 4; } } else { if (env->thumb) { - insn = tget16(env->regs[15] - 2); + /* FIXME - what to do if get_user() fails? */ + get_user(insn, env->regs[15] - 2, uint16_t); n = insn & 0xff; } else { - insn = tget32(env->regs[15] - 4); + /* FIXME - what to do if get_user() fails? */ + get_user(insn, env->regs[15] - 4, uint32_t); n = insn & 0xffffff; } } @@ -482,7 +487,8 @@ (int)sp_ptr, cwp1); #endif for(i = 0; i < 16; i++) { - tputl(sp_ptr, env->regbase[get_reg_index(env, cwp1, 8 + i)]); + /* FIXME - what to do if put_user() fails? */ + put_user(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr, abi_ulong); sp_ptr += sizeof(abi_ulong); } } @@ -518,7 +524,8 @@ (int)sp_ptr, cwp1); #endif for(i = 0; i < 16; i++) { - env->regbase[get_reg_index(env, cwp1, 8 + i)] = tgetl(sp_ptr); + /* FIXME - what to do if get_user() fails? */ + get_user(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr, abi_ulong); sp_ptr += sizeof(abi_ulong); } env->wim = new_wim; @@ -1495,10 +1502,11 @@ sp_reg = env->gpr[29][env->current_tc]; switch (nb_args) { /* these arguments are taken from the stack */ - case 8: arg8 = tgetl(sp_reg + 28); - case 7: arg7 = tgetl(sp_reg + 24); - case 6: arg6 = tgetl(sp_reg + 20); - case 5: arg5 = tgetl(sp_reg + 16); + /* FIXME - what to do if get_user() fails? */ + case 8: get_user(arg8, sp_reg + 28, abi_ulong); + case 7: get_user(arg7, sp_reg + 24, abi_ulong); + case 6: get_user(arg6, sp_reg + 20, abi_ulong); + case 5: get_user(arg5, sp_reg + 16, abi_ulong); default: break; } Index: qemu/linux-user/qemu.h =================================================================== --- qemu.orig/linux-user/qemu.h 2007-11-14 09:19:09.000000000 -0700 +++ qemu/linux-user/qemu.h 2007-11-14 11:23:00.000000000 -0700 @@ -217,7 +217,7 @@ int size = sizeof(*hptr);\ switch(size) {\ case 1:\ - *(uint8_t *)(hptr) = (typeof(*hptr))(x);\ + *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\ break;\ case 2:\ *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\ @@ -251,6 +251,8 @@ x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\ break;\ default:\ + /* avoid warning */\ + x = 0;\ abort();\ }\ 0;\ @@ -282,8 +284,11 @@ if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \ __ret = __get_user((x), __hptr); \ unlock_user(__hptr, __gaddr, 0); \ - } else \ + } else { \ + /* avoid warning */ \ + (x) = 0; \ __ret = -TARGET_EFAULT; \ + } \ __ret; \ }) @@ -354,20 +359,4 @@ #define unlock_user_struct(host_ptr, guest_addr, copy) \ unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0) -#define tget8(addr) ldub(addr) -#define tput8(addr, val) stb(addr, val) -#define tget16(addr) lduw(addr) -#define tput16(addr, val) stw(addr, val) -#define tget32(addr) ldl(addr) -#define tput32(addr, val) stl(addr, val) -#define tget64(addr) ldq(addr) -#define tput64(addr, val) stq(addr, val) -#if TARGET_ABI_BITS == 64 -#define tgetl(addr) ldq(addr) -#define tputl(addr, val) stq(addr, val) -#else -#define tgetl(addr) ldl(addr) -#define tputl(addr, val) stl(addr, val) -#endif - #endif /* QEMU_H */ Index: qemu/linux-user/syscall.c =================================================================== --- qemu.orig/linux-user/syscall.c 2007-11-14 09:19:09.000000000 -0700 +++ qemu/linux-user/syscall.c 2007-11-14 11:23:00.000000000 -0700 @@ -770,7 +770,8 @@ if (optlen < sizeof(uint32_t)) return -TARGET_EINVAL; - val = tget32(optval); + if (get_user(val, optval, uint32_t)) + return -TARGET_EFAULT; ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); break; case SOL_IP: @@ -792,9 +793,11 @@ case IP_MULTICAST_LOOP: val = 0; if (optlen >= sizeof(uint32_t)) { - val = tget32(optval); + if (get_user(val, optval, uint32_t)) + return -TARGET_EFAULT; } else if (optlen >= 1) { - val = tget8(optval); + if (get_user(val, optval, uint8_t)) + return -TARGET_EFAULT; } ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); break; @@ -866,9 +869,10 @@ goto unimplemented; } if (optlen < sizeof(uint32_t)) - return -TARGET_EINVAL; + return -TARGET_EINVAL; - val = tget32(optval); + if (get_user(val, optval, uint32_t)) + return -TARGET_EFAULT; ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val))); break; default: @@ -904,7 +908,8 @@ case SOL_TCP: /* TCP options all take an 'int' value. */ int_case: - len = tget32(optlen); + if (get_user(len, optlen, uint32_t)) + return -TARGET_EFAULT; if (len < 0) return -TARGET_EINVAL; lv = sizeof(int); @@ -914,11 +919,15 @@ val = tswap32(val); if (len > lv) len = lv; - if (len == 4) - tput32(optval, val); - else - tput8(optval, val); - tput32(optlen, len); + if (len == 4) { + if (put_user(val, optval, uint32_t)) + return -TARGET_EFAULT; + } else { + if (put_user(val, optval, target_char)) + return -TARGET_EFAULT; + } + if (put_user(len, optlen, target_socklen_t)) + return -TARGET_EFAULT; break; case SOL_IP: switch(optname) { @@ -937,7 +946,8 @@ #endif case IP_MULTICAST_TTL: case IP_MULTICAST_LOOP: - len = tget32(optlen); + if (get_user(len, optlen, uint32_t)) + return -TARGET_EFAULT; if (len < 0) return -TARGET_EINVAL; lv = sizeof(int); @@ -946,13 +956,15 @@ return ret; if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) { len = 1; - tput32(optlen, len); - tput8(optval, val); + if (put_user(len, optlen, target_socklen_t) + || put_user(val, optval, uint8_t)) + return -TARGET_EFAULT; } else { if (len > sizeof(int)) len = sizeof(int); - tput32(optlen, len); - tput32(optval, val); + if (put_user(len, optlen, target_socklen_t) + || put_user(val, optval, uint32_t)) + return -TARGET_EFAULT; } break; default: @@ -1130,63 +1142,82 @@ /* do_accept() Must return target values and target errnos. */ static abi_long do_accept(int fd, abi_ulong target_addr, - abi_ulong target_addrlen) + abi_ulong target_addrlen_addr) { - socklen_t addrlen = tget32(target_addrlen); - void *addr = alloca(addrlen); + socklen_t addrlen; + void *addr; abi_long ret; + if (get_user(addrlen, target_addrlen_addr, target_socklen_t)) + return -TARGET_EFAULT; + + addr = alloca(addrlen); + ret = get_errno(accept(fd, addr, &addrlen)); if (!is_error(ret)) { host_to_target_sockaddr(target_addr, addr, addrlen); - tput32(target_addrlen, addrlen); + if (put_user(addrlen, target_addrlen_addr, target_socklen_t)) + ret = -TARGET_EFAULT; } return ret; } /* do_getpeername() Must return target values and target errnos. */ static abi_long do_getpeername(int fd, abi_ulong target_addr, - abi_ulong target_addrlen) + abi_ulong target_addrlen_addr) { - socklen_t addrlen = tget32(target_addrlen); - void *addr = alloca(addrlen); + socklen_t addrlen; + void *addr; abi_long ret; + if (get_user(addrlen, target_addrlen_addr, target_socklen_t)) + return -TARGET_EFAULT; + + addr = alloca(addrlen); + ret = get_errno(getpeername(fd, addr, &addrlen)); if (!is_error(ret)) { host_to_target_sockaddr(target_addr, addr, addrlen); - tput32(target_addrlen, addrlen); + if (put_user(addrlen, target_addrlen_addr, target_socklen_t)) + ret = -TARGET_EFAULT; } return ret; } /* do_getsockname() Must return target values and target errnos. */ static abi_long do_getsockname(int fd, abi_ulong target_addr, - abi_ulong target_addrlen) + abi_ulong target_addrlen_addr) { - socklen_t addrlen = tget32(target_addrlen); - void *addr = alloca(addrlen); + socklen_t addrlen; + void *addr; abi_long ret; + if (get_user(addrlen, target_addrlen_addr, target_socklen_t)) + return -TARGET_EFAULT; + + addr = alloca(addrlen); + ret = get_errno(getsockname(fd, addr, &addrlen)); if (!is_error(ret)) { host_to_target_sockaddr(target_addr, addr, addrlen); - tput32(target_addrlen, addrlen); + if (put_user(addrlen, target_addrlen_addr, target_socklen_t)) + ret = -TARGET_EFAULT; } return ret; } /* do_socketpair() Must return target values and target errnos. */ static abi_long do_socketpair(int domain, int type, int protocol, - abi_ulong target_tab) + abi_ulong target_tab_addr) { int tab[2]; abi_long ret; ret = get_errno(socketpair(domain, type, protocol, tab)); if (!is_error(ret)) { - tput32(target_tab, tab[0]); - tput32(target_tab + 4, tab[1]); + if (put_user(tab[0], target_tab_addr, target_int) + || put_user(tab[1], target_tab_addr + sizeof(target_int), target_int)) + ret = -TARGET_EFAULT; } return ret; } @@ -1227,7 +1258,10 @@ if (!host_msg) return -TARGET_EFAULT; if (target_addr) { - addrlen = tget32(target_addrlen); + if (get_user(addrlen, target_addrlen, target_socklen_t)) { + ret = -TARGET_EFAULT; + goto fail; + } addr = alloca(addrlen); ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen)); } else { @@ -1237,10 +1271,14 @@ if (!is_error(ret)) { if (target_addr) { host_to_target_sockaddr(target_addr, addr, addrlen); - tput32(target_addrlen, addrlen); + if (put_user(addrlen, target_addrlen, socklen_t)) { + ret = -TARGET_EFAULT; + goto fail; + } } unlock_user(host_msg, msg, len); } else { +fail: unlock_user(host_msg, msg, 0); } return ret; @@ -1256,112 +1294,187 @@ switch(num) { case SOCKOP_socket: { - int domain = tgetl(vptr); - int type = tgetl(vptr + n); - int protocol = tgetl(vptr + 2 * n); + int domain, type, protocol; + + if (get_user(domain, vptr, target_int) + || get_user(type, vptr + n, target_int) + || get_user(protocol, vptr + 2 * n, target_int)) + return -TARGET_EFAULT; + ret = do_socket(domain, type, protocol); } break; case SOCKOP_bind: { - int sockfd = tgetl(vptr); - abi_ulong target_addr = tgetl(vptr + n); - socklen_t addrlen = tgetl(vptr + 2 * n); + int sockfd; + abi_ulong target_addr; + socklen_t addrlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(target_addr, vptr + n, abi_ulong) + || get_user(addrlen, vptr + 2 * n, target_socklen_t)) + return -TARGET_EFAULT; + ret = do_bind(sockfd, target_addr, addrlen); } break; case SOCKOP_connect: { - int sockfd = tgetl(vptr); - abi_ulong target_addr = tgetl(vptr + n); - socklen_t addrlen = tgetl(vptr + 2 * n); + int sockfd; + abi_ulong target_addr; + socklen_t addrlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(target_addr, vptr + n, abi_ulong) + || get_user(addrlen, vptr + 2 * n, target_socklen_t)) + return -TARGET_EFAULT; + ret = do_connect(sockfd, target_addr, addrlen); } break; case SOCKOP_listen: { - int sockfd = tgetl(vptr); - int backlog = tgetl(vptr + n); + int sockfd, backlog; + + if (get_user(sockfd, vptr, target_int) + || get_user(backlog, vptr + n, target_int)) + return -TARGET_EFAULT; + ret = get_errno(listen(sockfd, backlog)); } break; case SOCKOP_accept: { - int sockfd = tgetl(vptr); - abi_ulong target_addr = tgetl(vptr + n); - abi_ulong target_addrlen = tgetl(vptr + 2 * n); + int sockfd; + abi_ulong target_addr, target_addrlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(target_addr, vptr + n, abi_ulong) + || get_user(target_addrlen, vptr + 2 * n, target_socklen_t)) + return -TARGET_EFAULT; + ret = do_accept(sockfd, target_addr, target_addrlen); } break; case SOCKOP_getsockname: { - int sockfd = tgetl(vptr); - abi_ulong target_addr = tgetl(vptr + n); - abi_ulong target_addrlen = tgetl(vptr + 2 * n); + int sockfd; + abi_ulong target_addr, target_addrlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(target_addr, vptr + n, abi_ulong) + || get_user(target_addrlen, vptr + 2 * n, target_socklen_t)) + return -TARGET_EFAULT; + ret = do_getsockname(sockfd, target_addr, target_addrlen); } break; case SOCKOP_getpeername: { - int sockfd = tgetl(vptr); - abi_ulong target_addr = tgetl(vptr + n); - abi_ulong target_addrlen = tgetl(vptr + 2 * n); + int sockfd; + abi_ulong target_addr, target_addrlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(target_addr, vptr + n, abi_ulong) + || get_user(target_addrlen, vptr + 2 * n, target_socklen_t)) + return -TARGET_EFAULT; + ret = do_getpeername(sockfd, target_addr, target_addrlen); } break; case SOCKOP_socketpair: { - int domain = tgetl(vptr); - int type = tgetl(vptr + n); - int protocol = tgetl(vptr + 2 * n); - abi_ulong tab = tgetl(vptr + 3 * n); + int domain, type, protocol; + abi_ulong tab; + + if (get_user(domain, vptr, target_int) + || get_user(type, vptr + n, target_int) + || get_user(protocol, vptr + 2 * n, target_int) + || get_user(tab, vptr + 3 * n, abi_ulong)) + return -TARGET_EFAULT; + ret = do_socketpair(domain, type, protocol, tab); } break; case SOCKOP_send: { - int sockfd = tgetl(vptr); - abi_ulong msg = tgetl(vptr + n); - size_t len = tgetl(vptr + 2 * n); - int flags = tgetl(vptr + 3 * n); + int sockfd; + abi_ulong msg; + size_t len; + int flags; + + if (get_user(sockfd, vptr, target_int) + || get_user(msg, vptr + n, abi_ulong) + || get_user(len, vptr + 2 * n, target_size_t) + || get_user(flags, vptr + 3 * n, target_int)) + return -TARGET_EFAULT; + ret = do_sendto(sockfd, msg, len, flags, 0, 0); } break; case SOCKOP_recv: { - int sockfd = tgetl(vptr); - abi_ulong msg = tgetl(vptr + n); - size_t len = tgetl(vptr + 2 * n); - int flags = tgetl(vptr + 3 * n); + int sockfd; + abi_ulong msg; + size_t len; + int flags; + + if (get_user(sockfd, vptr, target_int) + || get_user(msg, vptr + n, abi_ulong) + || get_user(len, vptr + 2 * n, target_size_t) + || get_user(flags, vptr + 3 * n, target_int)) + return -TARGET_EFAULT; + ret = do_recvfrom(sockfd, msg, len, flags, 0, 0); } break; case SOCKOP_sendto: { - int sockfd = tgetl(vptr); - abi_ulong msg = tgetl(vptr + n); - size_t len = tgetl(vptr + 2 * n); - int flags = tgetl(vptr + 3 * n); - abi_ulong addr = tgetl(vptr + 4 * n); - socklen_t addrlen = tgetl(vptr + 5 * n); + int sockfd; + abi_ulong msg; + size_t len; + int flags; + abi_ulong addr; + socklen_t addrlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(msg, vptr + n, abi_ulong) + || get_user(len, vptr + 2 * n, target_size_t) + || get_user(flags, vptr + 3 * n, target_int) + || get_user(addr, vptr + 4 * n, abi_ulong) + || get_user(addrlen, vptr + 5 * n, target_socklen_t)) + return -TARGET_EFAULT; + ret = do_sendto(sockfd, msg, len, flags, addr, addrlen); } break; case SOCKOP_recvfrom: { - int sockfd = tgetl(vptr); - abi_ulong msg = tgetl(vptr + n); - size_t len = tgetl(vptr + 2 * n); - int flags = tgetl(vptr + 3 * n); - abi_ulong addr = tgetl(vptr + 4 * n); - abi_ulong addrlen = tgetl(vptr + 5 * n); + int sockfd; + abi_ulong msg; + size_t len; + int flags; + abi_ulong addr; + socklen_t addrlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(msg, vptr + n, abi_ulong) + || get_user(len, vptr + 2 * n, target_size_t) + || get_user(flags, vptr + 3 * n, target_int) + || get_user(addr, vptr + 4 * n, abi_ulong) + || get_user(addrlen, vptr + 5 * n, target_socklen_t)) + return -TARGET_EFAULT; + ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen); } break; case SOCKOP_shutdown: { - int sockfd = tgetl(vptr); - int how = tgetl(vptr + n); + int sockfd, how; + + if (get_user(sockfd, vptr, target_int) + || get_user(how, vptr + n, target_int)) + return -TARGET_EFAULT; ret = get_errno(shutdown(sockfd, how)); } @@ -1373,9 +1486,10 @@ abi_ulong target_msg; int flags; - fd = tgetl(vptr); - target_msg = tgetl(vptr + n); - flags = tgetl(vptr + 2 * n); + if (get_user(fd, vptr, target_int) + || get_user(target_msg, vptr + n, abi_ulong) + || get_user(flags, vptr + 2 * n, target_int)) + return -TARGET_EFAULT; ret = do_sendrecvmsg(fd, target_msg, flags, (num == SOCKOP_sendmsg)); @@ -1383,24 +1497,38 @@ break; case SOCKOP_setsockopt: { - int sockfd = tgetl(vptr); - int level = tgetl(vptr + n); - int optname = tgetl(vptr + 2 * n); - abi_ulong optval = tgetl(vptr + 3 * n); - socklen_t optlen = tgetl(vptr + 4 * n); + int sockfd; + int level; + int optname; + abi_ulong optval; + socklen_t optlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(level, vptr + n, target_int) + || get_user(optname, vptr + 2 * n, target_int) + || get_user(optval, vptr + 3 * n, abi_ulong) + || get_user(optlen, vptr + 4 * n, target_socklen_t)) + return -TARGET_EFAULT; ret = do_setsockopt(sockfd, level, optname, optval, optlen); } break; case SOCKOP_getsockopt: { - int sockfd = tgetl(vptr); - int level = tgetl(vptr + n); - int optname = tgetl(vptr + 2 * n); - abi_ulong optval = tgetl(vptr + 3 * n); - abi_ulong poptlen = tgetl(vptr + 4 * n); + int sockfd; + int level; + int optname; + abi_ulong optval; + socklen_t optlen; + + if (get_user(sockfd, vptr, target_int) + || get_user(level, vptr + n, target_int) + || get_user(optname, vptr + 2 * n, target_int) + || get_user(optval, vptr + 3 * n, abi_ulong) + || get_user(optlen, vptr + 4 * n, target_socklen_t)) + return -TARGET_EFAULT; - ret = do_getsockopt(sockfd, level, optname, optval, poptlen); + ret = do_getsockopt(sockfd, level, optname, optval, optlen); } break; default: @@ -2757,10 +2885,8 @@ unlock_user(p, arg2, 0); break; case TARGET_NR_open: - if (!(p = lock_user_string(arg1))) { - return -TARGET_EFAULT; - goto fail; - } + if (!(p = lock_user_string(arg1))) + goto efault; ret = get_errno(open(path(p), target_to_host_bitmask(arg2, fcntl_flags_tbl), arg3)); @@ -2793,8 +2919,9 @@ { int status; ret = get_errno(waitpid(arg1, &status, arg3)); - if (!is_error(ret) && arg2) - tput32(arg2, status); + if (!is_error(ret) && arg2 + && put_user(status, arg2, target_int)) + goto efault; } break; #endif @@ -2867,56 +2994,71 @@ argc = 0; guest_argp = arg2; - for (gp = guest_argp; tgetl(gp); gp++) + for (gp = guest_argp; ; gp++) { + if (get_user(guest_argp, gp, abi_ulong)) + goto efault; + if (!guest_argp) + break; argc++; + } envc = 0; guest_envp = arg3; - for (gp = guest_envp; tgetl(gp); gp++) + for (gp = guest_envp; ; gp++) { + if (get_user(guest_envp, gp, abi_ulong)) + goto efault; + if (!guest_envp) + break; envc++; + } argp = alloca((argc + 1) * sizeof(void *)); envp = alloca((envc + 1) * sizeof(void *)); for (gp = guest_argp, q = argp; ; gp += sizeof(abi_ulong), q++) { - addr = tgetl(gp); + if (get_user(addr, gp, abi_ulong)) + goto execve_efault; if (!addr) break; - if (!(*q = lock_user_string(addr))) { - ret = -TARGET_EFAULT; - goto execve_fail; - } + if (!(*q = lock_user_string(addr))) + goto execve_efault; } *q = NULL; for (gp = guest_envp, q = envp; ; gp += sizeof(abi_ulong), q++) { - addr = tgetl(gp); + if (get_user(addr, gp, abi_ulong)) + goto execve_efault; if (!addr) break; - if (!(*q = lock_user_string(addr))) { - ret = -TARGET_EFAULT; - goto execve_fail; - } + if (!(*q = lock_user_string(addr))) + goto execve_efault; } *q = NULL; - if (!(p = lock_user_string(arg1))) { - ret = -TARGET_EFAULT; - goto execve_fail; - } + if (!(p = lock_user_string(arg1))) + goto execve_efault; ret = get_errno(execve(p, argp, envp)); unlock_user(p, arg1, 0); - execve_fail: + goto execve_end; + + execve_efault: + ret = -TARGET_EFAULT; + + execve_end: for (gp = guest_argp, q = argp; *q; gp += sizeof(abi_ulong), q++) { - addr = tgetl(gp); + if (get_user(addr, gp, abi_ulong) + || !addr) + break; unlock_user(*q, addr, 0); } for (gp = guest_envp, q = envp; *q; gp += sizeof(abi_ulong), q++) { - addr = tgetl(gp); + if (get_user(addr, gp, abi_ulong) + || !addr) + break; unlock_user(*q, addr, 0); } } @@ -2932,8 +3074,10 @@ { time_t host_time; ret = get_errno(time(&host_time)); - if (!is_error(ret) && arg1) - tputl(arg1, host_time); + if (!is_error(ret) + && arg1 + && put_user(host_time, arg1, target_time_t)) + goto efault; } break; #endif @@ -3009,7 +3153,8 @@ case TARGET_NR_stime: { time_t host_time; - host_time = tgetl(arg1); + if (get_user(host_time, arg1, target_time_t)) + goto efault; ret = get_errno(stime(&host_time)); } break; @@ -3176,8 +3321,9 @@ env->gpr[3][env->current_tc] = host_pipe[1]; ret = host_pipe[0]; #else - tput32(arg1, host_pipe[0]); - tput32(arg1 + 4, host_pipe[1]); + if (put_user(host_pipe[0], arg1, target_int) + || put_user(host_pipe[1], arg1 + sizeof(target_int), target_int)) + goto efault; #endif } } @@ -4118,11 +4264,12 @@ rusage_ptr = NULL; ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); if (!is_error(ret)) { - if (status_ptr) - tputl(status_ptr, status); - if (target_rusage) { - host_to_target_rusage(target_rusage, &rusage); + if (status_ptr) { + if (put_user(status, status_ptr, target_int)) + goto efault; } + if (target_rusage) + host_to_target_rusage(target_rusage, &rusage); } } break; @@ -4255,11 +4402,13 @@ { #if defined (__x86_64__) ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5)); - tput64(arg4, ret); + if (put_user(ret, arg4, target_loff_t)) + goto efault; #else int64_t res; ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); - tput64(arg4, res); + if (put_user(res, arg4, target_loff_t)) + goto efault; #endif } break; @@ -4526,8 +4675,9 @@ { int deathsig; ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5)); - if (!is_error(ret) && arg2) - tput32(arg2, deathsig); + if (!is_error(ret) && arg2 + && put_user(deathsig, arg2, target_ulong)) + goto efault; } break; default: @@ -4779,9 +4929,10 @@ uid_t ruid, euid, suid; ret = get_errno(getresuid(&ruid, &euid, &suid)); if (!is_error(ret)) { - tput16(arg1, tswap16(high2lowuid(ruid))); - tput16(arg2, tswap16(high2lowuid(euid))); - tput16(arg3, tswap16(high2lowuid(suid))); + if (put_user(high2lowuid(ruid), arg1, target_uid_t) + || put_user(high2lowuid(euid), arg2, target_uid_t) + || put_user(high2lowuid(suid), arg3, target_uid_t)) + goto efault; } } break; @@ -4799,9 +4950,10 @@ gid_t rgid, egid, sgid; ret = get_errno(getresgid(&rgid, &egid, &sgid)); if (!is_error(ret)) { - tput16(arg1, tswap16(high2lowgid(rgid))); - tput16(arg2, tswap16(high2lowgid(egid))); - tput16(arg3, tswap16(high2lowgid(sgid))); + if (put_user(high2lowgid(rgid), arg1, target_gid_t) + || put_user(high2lowgid(egid), arg2, target_gid_t) + || put_user(high2lowgid(sgid), arg3, target_gid_t)) + goto efault; } } break; @@ -4924,9 +5076,10 @@ uid_t ruid, euid, suid; ret = get_errno(getresuid(&ruid, &euid, &suid)); if (!is_error(ret)) { - tput32(arg1, tswap32(ruid)); - tput32(arg2, tswap32(euid)); - tput32(arg3, tswap32(suid)); + if (put_user(ruid, arg1, target_uid32_t) + || put_user(euid, arg2, target_uid32_t) + || put_user(suid, arg3, target_uid32_t)) + goto efault; } } break; @@ -4942,9 +5095,10 @@ gid_t rgid, egid, sgid; ret = get_errno(getresgid(&rgid, &egid, &sgid)); if (!is_error(ret)) { - tput32(arg1, tswap32(rgid)); - tput32(arg2, tswap32(egid)); - tput32(arg3, tswap32(sgid)); + if (put_user(rgid, arg1, target_gid32_t) + || put_user(egid, arg2, target_gid32_t) + || put_user(sgid, arg3, target_gid32_t)) + goto efault; } } break; Index: qemu/arm-semi.c =================================================================== --- qemu.orig/arm-semi.c 2007-11-14 09:19:09.000000000 -0700 +++ qemu/arm-semi.c 2007-11-14 12:11:44.000000000 -0700 @@ -165,8 +165,14 @@ #endif } -#define ARG(n) tget32(args + (n) * 4) -#define SET_ARG(n, val) tput32(args + (n) * 4,val) +#define ARG(n) \ +({ \ + abi_ulong __arg; \ + /* FIXME - handle get_user() failure */ \ + get_user(__arg, args + (n) * 4, abi_ulong); \ + __arg; \ +}) +#define SET_ARG(n, val) put_user(val, args + (n) * 4, abi_ulong) uint32_t do_arm_semihosting(CPUState *env) { target_ulong args; @@ -213,7 +219,11 @@ } case SYS_WRITEC: { - char c = tget8(args); + char c; + + if (get_user(c, args, target_char)) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; /* Write to debug console. stderr is near enough. */ if (use_gdb_syscalls()) { gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args); Index: qemu/target-arm/nwfpe/fpa11_cpdt.c =================================================================== --- qemu.orig/target-arm/nwfpe/fpa11_cpdt.c 2007-11-14 09:19:09.000000000 -0700 +++ qemu/target-arm/nwfpe/fpa11_cpdt.c 2007-11-14 11:23:00.000000000 -0700 @@ -34,7 +34,8 @@ target_ulong addr = (target_ulong)(long)pMem; FPA11 *fpa11 = GET_FPA11(); fpa11->fType[Fn] = typeSingle; - fpa11->fpreg[Fn].fSingle = tget32(addr); + /* FIXME - handle failure of get_user() */ + get_user(fpa11->fpreg[Fn].fSingle, addr, uint32_t); } static inline @@ -46,11 +47,13 @@ p = (unsigned int*)&fpa11->fpreg[Fn].fDouble; fpa11->fType[Fn] = typeDouble; #ifdef WORDS_BIGENDIAN - p[0] = tget32(addr); /* sign & exponent */ - p[1] = tget32(addr + 4); + /* FIXME - handle failure of get_user() */ + get_user(p[0], addr, uint32_t); /* sign & exponent */ + get_user(p[1], addr + 4, uint32_t); #else - p[0] = tget32(addr + 4); - p[1] = tget32(addr); /* sign & exponent */ + /* FIXME - handle failure of get_user() */ + get_user(p[0], addr + 4, uint32_t); + get_user(p[1], addr, uint32_t); /* sign & exponent */ #endif } @@ -62,9 +65,10 @@ unsigned int *p; p = (unsigned int*)&fpa11->fpreg[Fn].fExtended; fpa11->fType[Fn] = typeExtended; - p[0] = tget32(addr); /* sign & exponent */ - p[1] = tget32(addr + 8); /* ls bits */ - p[2] = tget32(addr + 4); /* ms bits */ + /* FIXME - handle failure of get_user() */ + get_user(p[0], addr, uint32_t); /* sign & exponent */ + get_user(p[1], addr + 8, uint32_t); /* ls bits */ + get_user(p[2], addr + 4, uint32_t); /* ms bits */ } static inline @@ -76,7 +80,8 @@ unsigned long x; p = (unsigned int*)&(fpa11->fpreg[Fn]); - x = tget32(addr); + /* FIXME - handle failure of get_user() */ + get_user(x, addr, uint32_t); fpa11->fType[Fn] = (x >> 14) & 0x00000003; switch (fpa11->fType[Fn]) @@ -84,16 +89,18 @@ case typeSingle: case typeDouble: { - p[0] = tget32(addr + 8); /* Single */ - p[1] = tget32(addr + 4); /* double msw */ + /* FIXME - handle failure of get_user() */ + get_user(p[0], addr + 8, uint32_t); /* Single */ + get_user(p[1], addr + 4, uint32_t); /* double msw */ p[2] = 0; /* empty */ } break; case typeExtended: { - p[1] = tget32(addr + 8); - p[2] = tget32(addr + 4); /* msw */ + /* FIXME - handle failure of get_user() */ + get_user(p[1], addr + 8, uint32_t); + get_user(p[2], addr + 4, uint32_t); /* msw */ p[0] = (x & 0x80003fff); } break; @@ -121,7 +128,8 @@ default: val = fpa11->fpreg[Fn].fSingle; } - tput32(addr, p[0]); + /* FIXME - handle put_user() failures */ + put_user(p[0], addr, uint32_t); } static inline @@ -144,12 +152,13 @@ default: val = fpa11->fpreg[Fn].fDouble; } + /* FIXME - handle put_user() failures */ #ifdef WORDS_BIGENDIAN - tput32(addr, p[0]); /* msw */ - tput32(addr + 4, p[1]); /* lsw */ + put_user(p[0], addr, uint32_t); /* msw */ + put_user(p[1], addr + 4, uint32_t); /* lsw */ #else - tput32(addr, p[1]); /* msw */ - tput32(addr + 4, p[0]); /* lsw */ + put_user(p[1], addr, uint32_t); /* msw */ + put_user(p[0], addr + 4, uint32_t); /* lsw */ #endif } @@ -174,9 +183,10 @@ default: val = fpa11->fpreg[Fn].fExtended; } - tput32(addr, p[0]); /* sign & exp */ - tput32(addr + 8, p[1]); - tput32(addr + 4, p[2]); /* msw */ + /* FIXME - handle put_user() failures */ + put_user(p[0], addr, uint32_t); /* sign & exp */ + put_user(p[1], addr + 8, uint32_t); + put_user(p[2], addr + 4, uint32_t); /* msw */ } static inline @@ -194,17 +204,17 @@ case typeSingle: case typeDouble: { - tput32(addr + 8, p[0]); /* single */ - tput32(addr + 4, p[1]); /* double msw */ - tput32(addr, nType << 14); + put_user(p[0], addr + 8, uint32_t); /* single */ + put_user(p[1], addr + 4, uint32_t); /* double msw */ + put_user(nType << 14, addr, uint32_t); } break; case typeExtended: { - tput32(addr + 4, p[2]); /* msw */ - tput32(addr + 8, p[1]); - tput32(addr, (p[0] & 0x80003fff) | (nType << 14)); + put_user(p[2], addr + 4, uint32_t); /* msw */ + put_user(p[1], addr + 8, uint32_t); + put_user((p[0] & 0x80003fff) | (nType << 14), addr, uint32_t); } break; } Index: qemu/linux-user/linuxload.c =================================================================== --- qemu.orig/linux-user/linuxload.c 2007-11-14 09:19:09.000000000 -0700 +++ qemu/linux-user/linuxload.c 2007-11-14 11:23:00.000000000 -0700 @@ -126,21 +126,32 @@ sp -= (argc + 1) * n; argv = sp; if (push_ptr) { - sp -= n; tputl(sp, envp); - sp -= n; tputl(sp, argv); - } - sp -= n; tputl(sp, argc); + /* FIXME - handle put_user() failures */ + sp -= n; + put_user(envp, sp, abi_ulong); + sp -= n; + put_user(argv, sp, abi_ulong); + } + sp -= n; + /* FIXME - handle put_user() failures */ + put_user(argc, sp, abi_ulong); while (argc-- > 0) { - tputl(argv, stringp); argv += n; + /* FIXME - handle put_user() failures */ + put_user(stringp, argv, abi_ulong); + argv += n; stringp += target_strlen(stringp) + 1; } - tputl(argv, 0); + /* FIXME - handle put_user() failures */ + put_user(0, argv, abi_ulong); while (envc-- > 0) { - tputl(envp, stringp); envp += n; + /* FIXME - handle put_user() failures */ + put_user(stringp, envp, abi_ulong); + envp += n; stringp += target_strlen(stringp) + 1; } - tputl(envp, 0); + /* FIXME - handle put_user() failures */ + put_user(0, envp, abi_ulong); return sp; } Index: qemu/m68k-semi.c =================================================================== --- qemu.orig/m68k-semi.c 2007-11-14 11:46:30.000000000 -0700 +++ qemu/m68k-semi.c 2007-11-14 12:17:03.000000000 -0700 @@ -142,15 +142,23 @@ if (m68k_semi_is_fseek) { /* FIXME: We've already lost the high bits of the fseek return value. */ - tput32(args, 0); + /* FIXME - handle get_user() failure */ + put_user(0, args, uint32_t); args += 4; m68k_semi_is_fseek = 0; } - tput32(args, ret); - tput32(args + 4, errno); + /* FIXME - handle get_user() failure */ + put_user(ret, args, uint32_t); + put_user(errno, args + 4, uint32_t); } -#define ARG(x) tget32(args + (x) * 4) +#define ARG(n) \ +({ \ + abi_ulong __arg; \ + /* FIXME - handle get_user() failure */ \ + get_user(__arg, args + (n) * 4, abi_ulong); \ + __arg; \ +}) #define PARG(x) ((unsigned long)ARG(x)) void do_m68k_semihosting(CPUM68KState *env, int nr) { @@ -234,9 +245,10 @@ ARG(0), off, ARG(3)); } else { off = lseek(ARG(0), off, ARG(3)); - tput32(args, off >> 32); - tput32(args + 4, off); - tput32(args + 8, errno); + /* FIXME - handle get_user() failure */ + put_user(off >> 32, args, uint32_t); + put_user(off, args + 4, uint32_t); + put_user(errno, args + 8, uint32_t); } return; } @@ -382,6 +399,7 @@ cpu_abort(env, "Unsupported semihosting syscall %d\n", nr); result = 0; } - tput32(args, result); - tput32(args + 4, errno); + /* FIXME - handle get_user() failure */ + put_user(result, args, uint32_t); + put_user(errno, args + 4, uint32_t); }