}
/* do_sigaltstack() returns target values and errnos. */
-int do_sigaltstack(const struct target_sigaltstack *uss,
- struct target_sigaltstack *uoss,
- abi_ulong sp)
+/* compare linux/kernel/signal.c:do_sigaltstack() */
+abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
{
int ret;
struct target_sigaltstack oss;
/* XXX: test errors */
- if(uoss)
+ if(uoss_addr)
{
__put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
__put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
__put_user(sas_ss_flags(sp), &oss.ss_flags);
}
- if(uss)
+ if(uss_addr)
{
- struct target_sigaltstack ss;
+ struct target_sigaltstack *uss;
+ struct target_sigaltstack ss;
ret = -TARGET_EFAULT;
- if (!access_ok(VERIFY_READ, uss, sizeof(*uss))
+ if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
|| __get_user(ss.ss_sp, &uss->ss_sp)
|| __get_user(ss.ss_size, &uss->ss_size)
|| __get_user(ss.ss_flags, &uss->ss_flags))
goto out;
+ unlock_user_struct(uss, uss_addr, 0);
ret = -TARGET_EPERM;
if (on_sig_stack(sp))
target_sigaltstack_used.ss_size = ss.ss_size;
}
- if (uoss) {
+ if (uoss_addr) {
ret = -TARGET_EFAULT;
- if (!access_ok(VERIFY_WRITE, uoss, sizeof(oss)))
+ if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
goto out;
- memcpy(uoss, &oss, sizeof(oss));
}
ret = 0;
{
int err = 0;
+ /* already locked in setup_frame() */
err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
* Determine which stack to use..
*/
-static inline void *
+static inline abi_ulong
get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
{
unsigned long esp;
ka->sa.sa_restorer) {
esp = (unsigned long) ka->sa.sa_restorer;
}
- return g2h((esp - frame_size) & -8ul);
+ return (esp - frame_size) & -8ul;
}
+/* compare linux/arch/i386/kernel/signal.c:setup_frame() */
static void setup_frame(int sig, struct emulated_sigaction *ka,
target_sigset_t *set, CPUX86State *env)
{
+ abi_ulong frame_addr;
struct sigframe *frame;
int i, err = 0;
- frame = get_sigframe(ka, env, sizeof(*frame));
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
- if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
+
err |= __put_user((/*current->exec_domain
&& current->exec_domain->signal_invmap
&& sig < 32
cpu_x86_load_seg(env, R_CS, __USER_CS);
env->eflags &= ~TF_MASK;
+ unlock_user_struct(frame, frame_addr, 1);
+
return;
give_sigsegv:
+ unlock_user_struct(frame, frame_addr, 1);
if (sig == TARGET_SIGSEGV)
ka->sa._sa_handler = TARGET_SIG_DFL;
force_sig(TARGET_SIGSEGV /* , current */);
}
+/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUX86State *env)
{
+ abi_ulong frame_addr;
struct rt_sigframe *frame;
int i, err = 0;
- frame = get_sigframe(ka, env, sizeof(*frame));
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
- if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
err |= __put_user((/*current->exec_domain
cpu_x86_load_seg(env, R_CS, __USER_CS);
env->eflags &= ~TF_MASK;
+ unlock_user_struct(frame, frame_addr, 1);
+
return;
give_sigsegv:
+ unlock_user_struct(frame, frame_addr, 1);
if (sig == TARGET_SIGSEGV)
ka->sa._sa_handler = TARGET_SIG_DFL;
force_sig(TARGET_SIGSEGV /* , current */);
long do_sigreturn(CPUX86State *env)
{
- struct sigframe *frame = (struct sigframe *)g2h(env->regs[R_ESP] - 8);
+ struct sigframe *frame;
+ abi_ulong frame_addr = env->regs[R_ESP] - 8;
target_sigset_t target_set;
sigset_t set;
int eax, i;
#if defined(DEBUG_SIGNAL)
fprintf(stderr, "do_sigreturn\n");
#endif
+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+ goto badframe;
/* set blocked signals */
if (__get_user(target_set.sig[0], &frame->sc.oldmask))
goto badframe;
/* restore registers */
if (restore_sigcontext(env, &frame->sc, &eax))
goto badframe;
+ unlock_user_struct(frame, frame_addr, 0);
return eax;
badframe:
+ unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
return 0;
}
if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
goto badframe;
- if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT)
+ if (do_sigaltstack(h2g(&frame->uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
goto badframe;
return eax;
return err;
}
-static inline void *
+static inline abi_ulong
get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
{
unsigned long sp = regs->regs[13];
/*
* ATPCS B01 mandates 8-byte alignment
*/
- return g2h((sp - framesize) & ~7);
+ return (sp - framesize) & ~7;
}
static int
return 0;
}
+/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
static void setup_frame(int usig, struct emulated_sigaction *ka,
target_sigset_t *set, CPUState *regs)
{
- struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
+ struct sigframe *frame;
+ abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
int i, err = 0;
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+ return;
+
err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
if (__put_user(set->sig[i], &frame->extramask[i - 1]))
- return;
+ goto end;
}
if (err == 0)
err = setup_return(regs, ka, &frame->retcode, frame, usig);
+
+end:
+ unlock_user_struct(frame, frame_addr, 1);
// return err;
}
+/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
- struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
+ struct rt_sigframe *frame;
+ abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
struct target_sigaltstack stack;
int i, err = 0;
- if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
return /* 1 */;
__put_user_error(&frame->info, (abi_ulong *)&frame->pinfo, err);
__put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
__put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
__put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
- if (!access_ok(VERIFY_WRITE, &frame->uc.tuc_stack, sizeof(stack)))
- err = 1;
- else
- memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
+ err |= copy_to_user(&frame->uc.tuc_stack, &stack, sizeof(stack));
err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
env, set->sig[0]);
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
- return;
+ goto end;
}
if (err == 0)
env->regs[2] = (abi_ulong)frame->puc;
}
+end:
+ unlock_user_struct(frame, frame_addr, 1);
+
// return err;
}
if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
goto badframe;
- if (do_sigaltstack(&frame->uc.tuc_stack, NULL, get_sp_from_cpustate(env)) == -EFAULT)
+ if (do_sigaltstack(h2g(&frame->uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
goto badframe;
#if 0
abi_ulong *src, *dst;
grp = &ucp->uc_mcontext.mc_gregs;
- err = get_user(pc, &((*grp)[MC_PC]));
- err |= get_user(npc, &((*grp)[MC_NPC]));
+ err = __get_user(pc, &((*grp)[MC_PC]));
+ err |= __get_user(npc, &((*grp)[MC_NPC]));
if (err || ((pc | npc) & 3))
goto do_sigsegv;
if (env->regwptr[UREG_I1]) {
sigset_t set;
if (TARGET_NSIG_WORDS == 1) {
- if (get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
+ if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
goto do_sigsegv;
} else {
src = &ucp->uc_sigmask;
dst = &target_set;
for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
i++, dst++, src++)
- err |= get_user(dst, src);
+ err |= __get_user(dst, src);
if (err)
goto do_sigsegv;
}
}
env->pc = pc;
env->npc = npc;
- err |= get_user(env->y, &((*grp)[MC_Y]));
- err |= get_user(tstate, &((*grp)[MC_TSTATE]));
+ err |= __get_user(env->y, &((*grp)[MC_Y]));
+ err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
env->asi = (tstate >> 24) & 0xff;
PUT_CCR(env, tstate >> 32);
PUT_CWP64(env, tstate & 0x1f);
- err |= get_user(env->gregs[1], (&(*grp)[MC_G1]));
- err |= get_user(env->gregs[2], (&(*grp)[MC_G2]));
- err |= get_user(env->gregs[3], (&(*grp)[MC_G3]));
- err |= get_user(env->gregs[4], (&(*grp)[MC_G4]));
- err |= get_user(env->gregs[5], (&(*grp)[MC_G5]));
- err |= get_user(env->gregs[6], (&(*grp)[MC_G6]));
- err |= get_user(env->gregs[7], (&(*grp)[MC_G7]));
- err |= get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
- err |= get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
- err |= get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
- err |= get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
- err |= get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
- err |= get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
- err |= get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
- err |= get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
-
- err |= get_user(fp, &(ucp->uc_mcontext.mc_fp));
- err |= get_user(i7, &(ucp->uc_mcontext.mc_i7));
- err |= put_user(fp,
- (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
- err |= put_user(i7,
- (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
-
- err |= get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
- err |= get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
+ err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
+ err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
+ err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
+ err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
+ err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
+ err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
+ err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
+ err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
+ err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
+ err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
+ err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
+ err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
+ err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
+ err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
+ err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
+
+ err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
+ err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
+ err |= __put_user(fp,
+ (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
+ err |= __put_user(i7,
+ (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
+
+ err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
+ err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
dst = &env->fpr;
for (i = 0; i < 64; i++, dst++, src++)
- err |= get_user(dst, src);
- err |= get_user(env->fsr,
- &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
- err |= get_user(env->gsr,
- &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
+ err |= __get_user(dst, src);
+ err |= __get_user(env->fsr,
+ &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
+ err |= __get_user(env->gsr,
+ &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
if (err)
goto do_sigsegv;
sigprocmask(0, NULL, &set);
host_to_target_sigset_internal(&target_set, &set);
if (TARGET_NSIG_WORDS == 1)
- err |= put_user(target_set.sig[0],
- (abi_ulong *)&ucp->uc_sigmask);
+ err |= __put_user(target_set.sig[0],
+ (abi_ulong *)&ucp->uc_sigmask);
else {
src = &target_set;
dst = &ucp->uc_sigmask;
for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
i++, dst++, src++)
- err |= put_user(src, dst);
+ err |= __put_user(src, dst);
if (err)
goto do_sigsegv;
}
- err |= put_user(env->tstate, &((*grp)[MC_TSTATE]));
- err |= put_user(env->pc, &((*grp)[MC_PC]));
- err |= put_user(env->npc, &((*grp)[MC_NPC]));
- err |= put_user(env->y, &((*grp)[MC_Y]));
- err |= put_user(env->gregs[1], &((*grp)[MC_G1]));
- err |= put_user(env->gregs[2], &((*grp)[MC_G2]));
- err |= put_user(env->gregs[3], &((*grp)[MC_G3]));
- err |= put_user(env->gregs[4], &((*grp)[MC_G4]));
- err |= put_user(env->gregs[5], &((*grp)[MC_G5]));
- err |= put_user(env->gregs[6], &((*grp)[MC_G6]));
- err |= put_user(env->gregs[7], &((*grp)[MC_G7]));
- err |= put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
- err |= put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
- err |= put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
- err |= put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
- err |= put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
- err |= put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
- err |= put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
- err |= put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
-
- err |= get_user(fp,
- (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
- err |= get_user(i7,
- (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
- err |= put_user(fp, &(mcp->mc_fp));
- err |= put_user(i7, &(mcp->mc_i7));
+ err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
+ err |= __put_user(env->pc, &((*grp)[MC_PC]));
+ err |= __put_user(env->npc, &((*grp)[MC_NPC]));
+ err |= __put_user(env->y, &((*grp)[MC_Y]));
+ err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
+ err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
+ err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
+ err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
+ err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
+ err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
+ err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
+ err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
+ err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
+ err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
+ err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
+ err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
+ err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
+ err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
+ err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
+
+ err |= __get_user(fp,
+ (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
+ err |= __get_user(i7,
+ (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
+ err |= __put_user(fp, &(mcp->mc_fp));
+ err |= __put_user(i7, &(mcp->mc_i7));
src = &env->fpr;
dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
for (i = 0; i < 64; i++, dst++, src++)
- err |= put_user(src, dst);
- err |= put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
- err |= put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
- err |= put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
+ err |= __put_user(src, dst);
+ err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
+ err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
+ err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
if (err)
goto do_sigsegv;
/*
* Determine which stack to use..
*/
-static inline void *
+static inline abi_ulong
get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size)
{
unsigned long sp;
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
}
- return g2h((sp - frame_size) & ~7);
+ return (sp - frame_size) & ~7;
}
+/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
static void setup_frame(int sig, struct emulated_sigaction * ka,
- target_sigset_t *set, CPUState *regs)
+ target_sigset_t *set, CPUState *regs)
{
struct sigframe *frame;
+ abi_ulong frame_addr;
int i;
- frame = get_sigframe(ka, regs, sizeof(*frame));
- if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ frame_addr = get_sigframe(ka, regs, sizeof(*frame));
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
goto give_sigsegv;
install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
* since it returns to userland using eret
* we cannot do this here, and we must set PC directly */
regs->PC[regs->current_tc] = regs->gpr[25][regs->current_tc] = ka->sa._sa_handler;
+ unlock_user_struct(frame, frame_addr, 1);
return;
give_sigsegv:
+ unlock_user_struct(frame, frame_addr, 1);
force_sig(TARGET_SIGSEGV/*, current*/);
return;
}
long do_sigreturn(CPUState *regs)
{
struct sigframe *frame;
+ abi_ulong frame_addr;
sigset_t blocked;
target_sigset_t target_set;
int i;
#if defined(DEBUG_SIGNAL)
fprintf(stderr, "do_sigreturn\n");
#endif
- frame = (struct sigframe *) regs->gpr[29][regs->current_tc];
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ frame_addr = regs->gpr[29][regs->current_tc];
+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe;
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
#endif
}
-static inline void host_to_target_rusage(abi_ulong target_addr,
- const struct rusage *rusage)
+static inline abi_long host_to_target_rusage(abi_ulong target_addr,
+ const struct rusage *rusage)
{
struct target_rusage *target_rusage;
- lock_user_struct(target_rusage, target_addr, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
+ return -TARGET_EFAULT;
target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
unlock_user_struct(target_rusage, target_addr, 1);
+
+ return 0;
}
-static inline void target_to_host_timeval(struct timeval *tv,
- abi_ulong target_addr)
+static inline abi_long target_to_host_timeval(struct timeval *tv,
+ abi_ulong target_addr)
{
struct target_timeval *target_tv;
- lock_user_struct(target_tv, target_addr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_tv, target_addr, 1))
+ return -TARGET_EFAULT;
tv->tv_sec = tswapl(target_tv->tv_sec);
tv->tv_usec = tswapl(target_tv->tv_usec);
unlock_user_struct(target_tv, target_addr, 0);
+
+ return 0;
}
-static inline void host_to_target_timeval(abi_ulong target_addr,
- const struct timeval *tv)
+static inline abi_long host_to_target_timeval(abi_ulong target_addr,
+ const struct timeval *tv)
{
struct target_timeval *target_tv;
- lock_user_struct(target_tv, target_addr, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_tv, target_addr, 0))
+ return -TARGET_EFAULT;
target_tv->tv_sec = tswapl(tv->tv_sec);
target_tv->tv_usec = tswapl(tv->tv_usec);
unlock_user_struct(target_tv, target_addr, 1);
+
+ return 0;
}
int ok;
if (rfd_p) {
- target_rfds = lock_user(rfd_p, sizeof(abi_long) * n, 1);
+ target_rfds = lock_user(VERIFY_WRITE, rfd_p, sizeof(abi_long) * n, 1);
+ if (!target_rfds) {
+ ret = -TARGET_EFAULT;
+ goto end;
+ }
rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
} else {
target_rfds = NULL;
rfds_ptr = NULL;
}
if (wfd_p) {
- target_wfds = lock_user(wfd_p, sizeof(abi_long) * n, 1);
+ target_wfds = lock_user(VERIFY_WRITE, wfd_p, sizeof(abi_long) * n, 1);
+ if (!target_wfds) {
+ ret = -TARGET_EFAULT;
+ goto end;
+ }
wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
} else {
target_wfds = NULL;
wfds_ptr = NULL;
}
if (efd_p) {
- target_efds = lock_user(efd_p, sizeof(abi_long) * n, 1);
+ target_efds = lock_user(VERIFY_WRITE, efd_p, sizeof(abi_long) * n, 1);
+ if (!target_efds) {
+ ret = -TARGET_EFAULT;
+ goto end;
+ }
efds_ptr = target_to_host_fds(&efds, target_efds, n);
} else {
target_efds = NULL;
host_to_target_timeval(target_tv, &tv);
}
}
- if (target_rfds)
- unlock_user(target_rfds, rfd_p, ok ? sizeof(abi_long) * n : 0);
- if (target_wfds)
- unlock_user(target_wfds, wfd_p, ok ? sizeof(abi_long) * n : 0);
- if (target_efds)
- unlock_user(target_efds, efd_p, ok ? sizeof(abi_long) * n : 0);
+
+end:
+ unlock_user(target_rfds, rfd_p, ok ? sizeof(abi_long) * n : 0);
+ unlock_user(target_wfds, wfd_p, ok ? sizeof(abi_long) * n : 0);
+ unlock_user(target_efds, efd_p, ok ? sizeof(abi_long) * n : 0);
return ret;
}
-static inline void target_to_host_sockaddr(struct sockaddr *addr,
- abi_ulong target_addr,
- socklen_t len)
+static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
+ abi_ulong target_addr,
+ socklen_t len)
{
struct target_sockaddr *target_saddr;
- target_saddr = lock_user(target_addr, len, 1);
+ target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
+ if (!target_saddr)
+ return -TARGET_EFAULT;
memcpy(addr, target_saddr, len);
addr->sa_family = tswap16(target_saddr->sa_family);
unlock_user(target_saddr, target_addr, 0);
+
+ return 0;
}
-static inline void host_to_target_sockaddr(abi_ulong target_addr,
- struct sockaddr *addr,
- socklen_t len)
+static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
+ struct sockaddr *addr,
+ socklen_t len)
{
struct target_sockaddr *target_saddr;
- target_saddr = lock_user(target_addr, len, 0);
+ target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
+ if (!target_saddr)
+ return -TARGET_EFAULT;
memcpy(target_saddr, addr, len);
target_saddr->sa_family = tswap16(addr->sa_family);
unlock_user(target_saddr, target_addr, len);
+
+ return 0;
}
/* ??? Should this also swap msgh->name? */
return ret;
}
-static void lock_iovec(struct iovec *vec, abi_ulong target_addr,
- int count, int copy)
+/* FIXME
+ * lock_iovec()/unlock_iovec() have a return code of 0 for success where
+ * other lock functions have a return code of 0 for failure.
+ */
+static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
+ int count, int copy)
{
struct target_iovec *target_vec;
abi_ulong base;
- int i;
+ int i, j;
- target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
+ target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
+ if (!target_vec)
+ return -TARGET_EFAULT;
for(i = 0;i < count; i++) {
base = tswapl(target_vec[i].iov_base);
vec[i].iov_len = tswapl(target_vec[i].iov_len);
- vec[i].iov_base = lock_user(base, vec[i].iov_len, copy);
+ vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
+ if (!vec[i].iov_base)
+ goto fail;
+ }
+ unlock_user (target_vec, target_addr, 0);
+ return 0;
+ fail:
+ /* failure - unwind locks */
+ for (j = 0; j < i; j++) {
+ base = tswapl(target_vec[j].iov_base);
+ unlock_user(vec[j].iov_base, base, 0);
}
unlock_user (target_vec, target_addr, 0);
+ return -TARGET_EFAULT;
}
-static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
- int count, int copy)
+static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
+ int count, int copy)
{
struct target_iovec *target_vec;
abi_ulong base;
int i;
- target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
+ target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
+ if (!target_vec)
+ return -TARGET_EFAULT;
for(i = 0;i < count; i++) {
base = tswapl(target_vec[i].iov_base);
unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
}
unlock_user (target_vec, target_addr, 0);
+
+ return 0;
}
/* do_socket() Must return target values and target errnos. */
struct iovec *vec;
abi_ulong target_vec;
- lock_user_struct(msgp, target_msg, 1);
+ /* FIXME */
+ if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
+ msgp,
+ target_msg,
+ send ? 1 : 0))
+ return -TARGET_EFAULT;
if (msgp->msg_name) {
msg.msg_namelen = tswap32(msgp->msg_namelen);
msg.msg_name = alloca(msg.msg_namelen);
count = tswapl(msgp->msg_iovlen);
vec = alloca(count * sizeof(struct iovec));
target_vec = tswapl(msgp->msg_iov);
- lock_iovec(vec, target_vec, count, send);
+ lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
msg.msg_iovlen = count;
msg.msg_iov = vec;
host_to_target_cmsg(msgp, &msg);
}
unlock_iovec(vec, target_vec, count, !send);
+ unlock_user_struct(msgp, target_msg, send ? 0 : 1);
return ret;
}
void *host_msg;
abi_long ret;
- host_msg = lock_user(msg, len, 1);
+ host_msg = lock_user(VERIFY_READ, msg, len, 1);
+ if (!host_msg)
+ return -TARGET_EFAULT;
if (target_addr) {
addr = alloca(addrlen);
target_to_host_sockaddr(addr, target_addr, addrlen);
void *host_msg;
abi_long ret;
- host_msg = lock_user(msg, len, 0);
+ host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
+ if (!host_msg)
+ return -TARGET_EFAULT;
if (target_addr) {
addrlen = tget32(target_addrlen);
addr = alloca(addrlen);
abi_ulong __unused4;
};
-static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,
- abi_ulong target_addr)
+static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
+ abi_ulong target_addr)
{
struct target_ipc_perm *target_ip;
struct target_semid_ds *target_sd;
- lock_user_struct(target_sd, target_addr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
+ return -TARGET_EFAULT;
target_ip=&(target_sd->sem_perm);
host_ip->__key = tswapl(target_ip->__key);
host_ip->uid = tswapl(target_ip->uid);
host_ip->cgid = tswapl(target_ip->cgid);
host_ip->mode = tswapl(target_ip->mode);
unlock_user_struct(target_sd, target_addr, 0);
+ return 0;
}
-static inline void host_to_target_ipc_perm(abi_ulong target_addr,
- struct ipc_perm *host_ip)
+static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
+ struct ipc_perm *host_ip)
{
struct target_ipc_perm *target_ip;
struct target_semid_ds *target_sd;
- lock_user_struct(target_sd, target_addr, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
+ return -TARGET_EFAULT;
target_ip = &(target_sd->sem_perm);
target_ip->__key = tswapl(host_ip->__key);
target_ip->uid = tswapl(host_ip->uid);
target_ip->cgid = tswapl(host_ip->cgid);
target_ip->mode = tswapl(host_ip->mode);
unlock_user_struct(target_sd, target_addr, 1);
+ return 0;
}
-static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
- abi_ulong target_addr)
+static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
+ abi_ulong target_addr)
{
struct target_semid_ds *target_sd;
- lock_user_struct(target_sd, target_addr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
+ return -TARGET_EFAULT;
target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
host_sd->sem_otime = tswapl(target_sd->sem_otime);
host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
unlock_user_struct(target_sd, target_addr, 0);
+ return 0;
}
-static inline void host_to_target_semid_ds(abi_ulong target_addr,
- struct semid_ds *host_sd)
+static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
+ struct semid_ds *host_sd)
{
struct target_semid_ds *target_sd;
- lock_user_struct(target_sd, target_addr, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
+ return -TARGET_EFAULT;
host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
target_sd->sem_otime = tswapl(host_sd->sem_otime);
target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
unlock_user_struct(target_sd, target_addr, 1);
+ return 0;
}
union semun {
unsigned short int *array;
};
-static inline void target_to_host_semun(int cmd,
- union semun *host_su,
- abi_ulong target_addr,
- struct semid_ds *ds)
+static inline abi_long target_to_host_semun(int cmd,
+ union semun *host_su,
+ abi_ulong target_addr,
+ struct semid_ds *ds)
{
union target_semun *target_su;
switch( cmd ) {
case IPC_STAT:
case IPC_SET:
- lock_user_struct(target_su, target_addr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
+ return -TARGET_EFAULT;
target_to_host_semid_ds(ds,target_su->buf);
host_su->buf = ds;
unlock_user_struct(target_su, target_addr, 0);
break;
case GETVAL:
case SETVAL:
- lock_user_struct(target_su, target_addr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
+ return -TARGET_EFAULT;
host_su->val = tswapl(target_su->val);
unlock_user_struct(target_su, target_addr, 0);
break;
case GETALL:
case SETALL:
- lock_user_struct(target_su, target_addr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
+ return -TARGET_EFAULT;
*host_su->array = tswap16(*target_su->array);
unlock_user_struct(target_su, target_addr, 0);
break;
default:
gemu_log("semun operation not fully supported: %d\n", (int)cmd);
}
+ return 0;
}
-static inline void host_to_target_semun(int cmd,
- abi_ulong target_addr,
- union semun *host_su,
- struct semid_ds *ds)
+static inline abi_long host_to_target_semun(int cmd,
+ abi_ulong target_addr,
+ union semun *host_su,
+ struct semid_ds *ds)
{
union target_semun *target_su;
switch( cmd ) {
case IPC_STAT:
case IPC_SET:
- lock_user_struct(target_su, target_addr, 0);
+ if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
+ return -TARGET_EFAULT;
host_to_target_semid_ds(target_su->buf,ds);
unlock_user_struct(target_su, target_addr, 1);
break;
case GETVAL:
case SETVAL:
- lock_user_struct(target_su, target_addr, 0);
+ if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
+ return -TARGET_EFAULT;
target_su->val = tswapl(host_su->val);
unlock_user_struct(target_su, target_addr, 1);
break;
case GETALL:
case SETALL:
- lock_user_struct(target_su, target_addr, 0);
+ if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
+ return -TARGET_EFAULT;
*target_su->array = tswap16(*host_su->array);
unlock_user_struct(target_su, target_addr, 1);
break;
default:
gemu_log("semun operation not fully supported: %d\n", (int)cmd);
}
+ return 0;
}
static inline abi_long do_semctl(int first, int second, int third,
abi_ulong __unused5;
};
-static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
- abi_ulong target_addr)
+static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
+ abi_ulong target_addr)
{
struct target_msqid_ds *target_md;
- lock_user_struct(target_md, target_addr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
+ return -TARGET_EFAULT;
target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
host_md->msg_stime = tswapl(target_md->msg_stime);
host_md->msg_rtime = tswapl(target_md->msg_rtime);
host_md->msg_lspid = tswapl(target_md->msg_lspid);
host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
unlock_user_struct(target_md, target_addr, 0);
+ return 0;
}
-static inline void host_to_target_msqid_ds(abi_ulong target_addr,
- struct msqid_ds *host_md)
+static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
+ struct msqid_ds *host_md)
{
struct target_msqid_ds *target_md;
- lock_user_struct(target_md, target_addr, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
+ return -TARGET_EFAULT;
host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
target_md->msg_stime = tswapl(host_md->msg_stime);
target_md->msg_rtime = tswapl(host_md->msg_rtime);
target_md->msg_lspid = tswapl(host_md->msg_lspid);
target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
unlock_user_struct(target_md, target_addr, 1);
+ return 0;
}
static inline abi_long do_msgctl(int first, int second, abi_long ptr)
struct msgbuf *host_mb;
abi_long ret = 0;
- lock_user_struct(target_mb,msgp,0);
+ if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
+ return -TARGET_EFAULT;
host_mb = malloc(msgsz+sizeof(long));
host_mb->mtype = tswapl(target_mb->mtype);
memcpy(host_mb->mtext,target_mb->mtext,msgsz);
int msgflg)
{
struct target_msgbuf *target_mb;
+ char *target_mtext;
struct msgbuf *host_mb;
abi_long ret = 0;
- lock_user_struct(target_mb, msgp, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
+ return -TARGET_EFAULT;
host_mb = malloc(msgsz+sizeof(long));
ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
- if (ret > 0)
+ if (ret > 0) {
+ abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
+ target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
+ if (!target_mtext) {
+ ret = -TARGET_EFAULT;
+ goto end;
+ }
memcpy(target_mb->mtext, host_mb->mtext, ret);
+ unlock_user(target_mtext, target_mtext_addr, ret);
+ }
target_mb->mtype = tswapl(host_mb->mtype);
free(host_mb);
- unlock_user_struct(target_mb, msgp, 0);
+end:
+ if (target_mb)
+ unlock_user_struct(target_mb, msgp, 1);
return ret;
}
switch (call) {
case IPCOP_semop:
- ret = get_errno(semop(first,(struct sembuf *) ptr, second));
+ ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
break;
case IPCOP_semget:
case IPCOP_msgrcv:
{
+ /* XXX: this code is not correct */
struct ipc_kludge
{
void *__unbounded msgp;
long int msgtyp;
};
- struct ipc_kludge *foo = (struct ipc_kludge *) ptr;
+ struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
ret = do_msgrcv(first, (long)msgp, second, 0, third);
break;
}
}
- if (put_user(raddr, (abi_ulong *)third))
+ if (put_user(raddr, third, abi_ulong))
return -TARGET_EFAULT;
ret = 0;
break;
case IOC_R:
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
if (!is_error(ret)) {
- argptr = lock_user(arg, target_size, 0);
+ argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+ if (!argptr)
+ return -TARGET_EFAULT;
thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
unlock_user(argptr, arg, target_size);
}
break;
case IOC_W:
- argptr = lock_user(arg, target_size, 1);
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr)
+ return -TARGET_EFAULT;
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
unlock_user(argptr, arg, 0);
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
break;
default:
case IOC_RW:
- argptr = lock_user(arg, target_size, 1);
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr)
+ return -TARGET_EFAULT;
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
unlock_user(argptr, arg, 0);
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
if (!is_error(ret)) {
- argptr = lock_user(arg, target_size, 0);
+ argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+ if (!argptr)
+ return -TARGET_EFAULT;
thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
unlock_user(argptr, arg, target_size);
}
size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
if (size > bytecount)
size = bytecount;
- p = lock_user(ptr, size, 0);
- /* ??? Shoudl this by byteswapped? */
+ p = lock_user(VERIFY_WRITE, ptr, size, 0);
+ if (!p)
+ return -EFAULT;
+ /* ??? Should this by byteswapped? */
memcpy(p, ldt_table, size);
unlock_user(p, ptr, size);
return size;
if (bytecount != sizeof(ldt_info))
return -EINVAL;
- lock_user_struct(target_ldt_info, ptr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
+ return -EFAULT;
ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
ldt_info.limit = tswap32(target_ldt_info->limit);
switch(cmd) {
case TARGET_F_GETLK:
- lock_user_struct(target_fl, arg, 1);
+ if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
+ return -TARGET_EFAULT;
fl.l_type = tswap16(target_fl->l_type);
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswapl(target_fl->l_start);
unlock_user_struct(target_fl, arg, 0);
ret = fcntl(fd, cmd, &fl);
if (ret == 0) {
- lock_user_struct(target_fl, arg, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
+ return -TARGET_EFAULT;
target_fl->l_type = tswap16(fl.l_type);
target_fl->l_whence = tswap16(fl.l_whence);
target_fl->l_start = tswapl(fl.l_start);
case TARGET_F_SETLK:
case TARGET_F_SETLKW:
- lock_user_struct(target_fl, arg, 1);
+ if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
+ return -TARGET_EFAULT;
fl.l_type = tswap16(target_fl->l_type);
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswapl(target_fl->l_start);
break;
case TARGET_F_GETLK64:
- lock_user_struct(target_fl64, arg, 1);
+ if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
+ return -TARGET_EFAULT;
fl64.l_type = tswap16(target_fl64->l_type) >> 1;
fl64.l_whence = tswap16(target_fl64->l_whence);
fl64.l_start = tswapl(target_fl64->l_start);
unlock_user_struct(target_fl64, arg, 0);
ret = fcntl(fd, cmd >> 1, &fl64);
if (ret == 0) {
- lock_user_struct(target_fl64, arg, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
+ return -TARGET_EFAULT;
target_fl64->l_type = tswap16(fl64.l_type) >> 1;
target_fl64->l_whence = tswap16(fl64.l_whence);
target_fl64->l_start = tswapl(fl64.l_start);
break;
case TARGET_F_SETLK64:
case TARGET_F_SETLKW64:
- lock_user_struct(target_fl64, arg, 1);
+ if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
+ return -TARGET_EFAULT;
fl64.l_type = tswap16(target_fl64->l_type) >> 1;
fl64.l_whence = tswap16(target_fl64->l_whence);
fl64.l_start = tswapl(target_fl64->l_start);
fl64.l_len = tswapl(target_fl64->l_len);
fl64.l_pid = tswap16(target_fl64->l_pid);
unlock_user_struct(target_fl64, arg, 0);
- ret = fcntl(fd, cmd >> 1, &fl64);
+ ret = fcntl(fd, cmd >> 1, &fl64);
break;
case F_GETFL:
}
#endif
-static inline void target_to_host_timespec(struct timespec *host_ts,
- abi_ulong target_addr)
+static inline abi_long target_to_host_timespec(struct timespec *host_ts,
+ abi_ulong target_addr)
{
struct target_timespec *target_ts;
- lock_user_struct(target_ts, target_addr, 1);
+ if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
+ return -TARGET_EFAULT;
host_ts->tv_sec = tswapl(target_ts->tv_sec);
host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
unlock_user_struct(target_ts, target_addr, 0);
}
-static inline void host_to_target_timespec(abi_ulong target_addr,
- struct timespec *host_ts)
+static inline abi_long host_to_target_timespec(abi_ulong target_addr,
+ struct timespec *host_ts)
{
struct target_timespec *target_ts;
- lock_user_struct(target_ts, target_addr, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
+ return -TARGET_EFAULT;
target_ts->tv_sec = tswapl(host_ts->tv_sec);
target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
unlock_user_struct(target_ts, target_addr, 1);
break;
case TARGET_NR_read:
page_unprotect_range(arg2, arg3);
- p = lock_user(arg2, arg3, 0);
+ if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
+ goto efault;
ret = get_errno(read(arg1, p, arg3));
unlock_user(p, arg2, ret);
break;
case TARGET_NR_write:
- p = lock_user(arg2, arg3, 1);
+ if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
+ goto efault;
ret = get_errno(write(arg1, p, arg3));
unlock_user(p, arg2, 0);
break;
case TARGET_NR_open:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1))) {
+ return -TARGET_EFAULT;
+ goto fail;
+ }
ret = get_errno(open(path(p),
target_to_host_bitmask(arg2, fcntl_flags_tbl),
arg3));
break;
#if defined(TARGET_NR_openat) && defined(__NR_openat)
case TARGET_NR_openat:
- if (!arg2) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
- p = lock_user_string(arg2);
- if (!access_ok(VERIFY_READ, p, 1))
- /* Don't "goto fail" so that cleanup can happen. */
- ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_openat(arg1,
- path(p),
- target_to_host_bitmask(arg3, fcntl_flags_tbl),
- arg4));
- if (p)
- unlock_user(p, arg2, 0);
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
+ ret = get_errno(sys_openat(arg1,
+ path(p),
+ target_to_host_bitmask(arg3, fcntl_flags_tbl),
+ arg4));
+ unlock_user(p, arg2, 0);
break;
#endif
case TARGET_NR_close:
#endif
#ifdef TARGET_NR_creat /* not on alpha */
case TARGET_NR_creat:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(creat(p, arg2));
unlock_user(p, arg1, 0);
break;
void * p2;
p = lock_user_string(arg1);
p2 = lock_user_string(arg2);
- ret = get_errno(link(p, p2));
+ if (!p || !p2)
+ ret = -TARGET_EFAULT;
+ else
+ ret = get_errno(link(p, p2));
unlock_user(p2, arg2, 0);
unlock_user(p, arg1, 0);
}
break;
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
case TARGET_NR_linkat:
- if (!arg2 || !arg4) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
{
void * p2 = NULL;
+ if (!arg2 || !arg4)
+ goto efault;
p = lock_user_string(arg2);
p2 = lock_user_string(arg4);
- if (!access_ok(VERIFY_READ, p, 1)
- || !access_ok(VERIFY_READ, p2, 1))
- /* Don't "goto fail" so that cleanup can happen. */
+ if (!p || !p2)
ret = -TARGET_EFAULT;
else
ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
- if (p2)
- unlock_user(p, arg2, 0);
- if (p)
- unlock_user(p2, arg4, 0);
+ unlock_user(p, arg2, 0);
+ unlock_user(p2, arg4, 0);
}
break;
#endif
case TARGET_NR_unlink:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(unlink(p));
unlock_user(p, arg1, 0);
break;
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
case TARGET_NR_unlinkat:
- if (!arg2) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
- p = lock_user_string(arg2);
- if (!access_ok(VERIFY_READ, p, 1))
- /* Don't "goto fail" so that cleanup can happen. */
- ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_unlinkat(arg1, p, arg3));
- if (p)
- unlock_user(p, arg2, 0);
- break;
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
+ ret = get_errno(sys_unlinkat(arg1, p, arg3));
+ unlock_user(p, arg2, 0);
#endif
case TARGET_NR_execve:
{
addr = tgetl(gp);
if (!addr)
break;
- *q = lock_user_string(addr);
+ if (!(*q = lock_user_string(addr))) {
+ ret = -TARGET_EFAULT;
+ goto execve_fail;
+ }
}
*q = NULL;
addr = tgetl(gp);
if (!addr)
break;
- *q = lock_user_string(addr);
+ if (!(*q = lock_user_string(addr))) {
+ ret = -TARGET_EFAULT;
+ goto execve_fail;
+ }
}
*q = NULL;
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1))) {
+ ret = -TARGET_EFAULT;
+ goto execve_fail;
+ }
ret = get_errno(execve(p, argp, envp));
unlock_user(p, arg1, 0);
+ execve_fail:
for (gp = guest_argp, q = argp; *q;
gp += sizeof(abi_ulong), q++) {
addr = tgetl(gp);
}
break;
case TARGET_NR_chdir:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(chdir(p));
unlock_user(p, arg1, 0);
break;
break;
#endif
case TARGET_NR_mknod:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(mknod(p, arg2, arg3));
unlock_user(p, arg1, 0);
break;
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
case TARGET_NR_mknodat:
- if (!arg2) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
- p = lock_user_string(arg2);
- if (!access_ok(VERIFY_READ, p, 1))
- /* Don't "goto fail" so that cleanup can happen. */
- ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
- if (p)
- unlock_user(p, arg2, 0);
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
+ ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
+ unlock_user(p, arg2, 0);
break;
#endif
case TARGET_NR_chmod:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(chmod(p, arg2));
unlock_user(p, arg1, 0);
break;
p = lock_user_string(arg1);
p2 = lock_user_string(arg2);
p3 = lock_user_string(arg3);
- ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, (const void *)arg5));
- unlock_user(p, arg1, 0);
- unlock_user(p2, arg2, 0);
- unlock_user(p3, arg3, 0);
+ if (!p || !p2 || !p3)
+ ret = -TARGET_EFAULT;
+ else
+ /* FIXME - arg5 should be locked, but it isn't clear how to
+ * do that since it's not guaranteed to be a NULL-terminated
+ * string.
+ */
+ ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
+ unlock_user(p, arg1, 0);
+ unlock_user(p2, arg2, 0);
+ unlock_user(p3, arg3, 0);
break;
}
#ifdef TARGET_NR_umount
case TARGET_NR_umount:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(umount(p));
unlock_user(p, arg1, 0);
break;
struct utimbuf tbuf, *host_tbuf;
struct target_utimbuf *target_tbuf;
if (arg2) {
- lock_user_struct(target_tbuf, arg2, 1);
+ if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
+ goto efault;
tbuf.actime = tswapl(target_tbuf->actime);
tbuf.modtime = tswapl(target_tbuf->modtime);
unlock_user_struct(target_tbuf, arg2, 0);
} else {
host_tbuf = NULL;
}
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(utime(p, host_tbuf));
unlock_user(p, arg1, 0);
}
} else {
tvp = NULL;
}
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(utimes(p, tvp));
unlock_user(p, arg1, 0);
}
goto unimplemented;
#endif
case TARGET_NR_access:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(access(p, arg2));
unlock_user(p, arg1, 0);
break;
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
case TARGET_NR_faccessat:
- if (!arg2) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
- p = lock_user_string(arg2);
- if (!access_ok(VERIFY_READ, p, 1))
- /* Don't "goto fail" so that cleanup can happen. */
- ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
- if (p)
- unlock_user(p, arg2, 0);
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
+ ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
+ unlock_user(p, arg2, 0);
break;
#endif
#ifdef TARGET_NR_nice /* not on alpha */
void *p2;
p = lock_user_string(arg1);
p2 = lock_user_string(arg2);
- ret = get_errno(rename(p, p2));
+ if (!p || !p2)
+ ret = -TARGET_EFAULT;
+ else
+ ret = get_errno(rename(p, p2));
unlock_user(p2, arg2, 0);
unlock_user(p, arg1, 0);
}
break;
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
case TARGET_NR_renameat:
- if (!arg2 || !arg4) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
{
- void *p2 = NULL;
+ void *p2;
p = lock_user_string(arg2);
p2 = lock_user_string(arg4);
- if (!access_ok(VERIFY_READ, p, 1)
- || !access_ok(VERIFY_READ, p2, 1))
- /* Don't "goto fail" so that cleanup can happen. */
+ if (!p || !p2)
ret = -TARGET_EFAULT;
else
ret = get_errno(sys_renameat(arg1, p, arg3, p2));
- if (p2)
- unlock_user(p2, arg4, 0);
- if (p)
- unlock_user(p, arg2, 0);
+ unlock_user(p2, arg4, 0);
+ unlock_user(p, arg2, 0);
}
break;
#endif
case TARGET_NR_mkdir:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(mkdir(p, arg2));
unlock_user(p, arg1, 0);
break;
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
case TARGET_NR_mkdirat:
- if (!arg2) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
- p = lock_user_string(arg2);
- if (!access_ok(VERIFY_READ, p, 1))
- /* Don't "goto fail" so that cleanup can happen. */
- ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_mkdirat(arg1, p, arg3));
- if (p)
- unlock_user(p, arg2, 0);
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
+ ret = get_errno(sys_mkdirat(arg1, p, arg3));
+ unlock_user(p, arg2, 0);
break;
#endif
case TARGET_NR_rmdir:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(rmdir(p));
unlock_user(p, arg1, 0);
break;
struct tms tms;
ret = get_errno(times(&tms));
if (arg1) {
- tmsp = lock_user(arg1, sizeof(struct target_tms), 0);
+ tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
+ if (!tmsp)
+ goto efault;
tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
goto unimplemented;
#endif
case TARGET_NR_acct:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(acct(path(p)));
unlock_user(p, arg1, 0);
break;
#ifdef TARGET_NR_umount2 /* not on alpha */
case TARGET_NR_umount2:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(umount2(p, arg2));
unlock_user(p, arg1, 0);
break;
ret = get_errno(umask(arg1));
break;
case TARGET_NR_chroot:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(chroot(p));
unlock_user(p, arg1, 0);
break;
struct target_old_sigaction *old_act;
struct target_sigaction act, oact, *pact;
if (arg2) {
- lock_user_struct(old_act, arg2, 1);
+ if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
+ goto efault;
act._sa_handler = old_act->_sa_handler;
target_siginitset(&act.sa_mask, old_act->sa_mask);
act.sa_flags = old_act->sa_flags;
}
ret = get_errno(do_sigaction(arg1, pact, &oact));
if (!is_error(ret) && arg3) {
- lock_user_struct(old_act, arg3, 0);
+ if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
+ goto efault;
old_act->_sa_handler = oact._sa_handler;
old_act->sa_mask = oact.sa_mask.sig[0];
old_act->sa_flags = oact.sa_flags;
struct target_sigaction act, oact, *pact, *old_act;
if (arg2) {
- lock_user_struct(old_act, arg2, 1);
+ if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
+ goto efault;
act._sa_handler = old_act->_sa_handler;
target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
act.sa_flags = old_act->sa_flags;
ret = get_errno(do_sigaction(arg1, pact, &oact));
if (!is_error(ret) && arg3) {
- lock_user_struct(old_act, arg3, 0);
+ if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
+ goto efault;
old_act->_sa_handler = oact._sa_handler;
old_act->sa_flags = oact.sa_flags;
old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
struct target_sigaction *act;
struct target_sigaction *oact;
- if (arg2)
- lock_user_struct(act, arg2, 1);
- else
+ if (arg2) {
+ if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
+ goto efault;
+ } else
act = NULL;
- if (arg3)
- lock_user_struct(oact, arg3, 0);
- else
+ if (arg3) {
+ if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
+ ret = -TARGET_EFAULT;
+ goto rt_sigaction_fail;
+ }
+ } else
oact = NULL;
ret = get_errno(do_sigaction(arg1, act, oact));
- if (arg2)
+ rt_sigaction_fail:
+ if (act)
unlock_user_struct(act, arg2, 0);
- if (arg3)
+ if (oact)
unlock_user_struct(oact, arg3, 1);
}
break;
ret = -TARGET_EINVAL;
goto fail;
}
- p = lock_user(arg2, sizeof(target_sigset_t), 1);
+ if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
+ goto efault;
target_to_host_old_sigset(&set, p);
unlock_user(p, arg2, 0);
set_ptr = &set;
}
ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
if (!is_error(ret) && arg3) {
- p = lock_user(arg3, sizeof(target_sigset_t), 0);
+ if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
+ goto efault;
host_to_target_old_sigset(p, &oldset);
unlock_user(p, arg3, sizeof(target_sigset_t));
}
ret = -TARGET_EINVAL;
goto fail;
}
- p = lock_user(arg2, sizeof(target_sigset_t), 1);
+ if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
+ goto efault;
target_to_host_sigset(&set, p);
unlock_user(p, arg2, 0);
set_ptr = &set;
}
ret = get_errno(sigprocmask(how, set_ptr, &oldset));
if (!is_error(ret) && arg3) {
- p = lock_user(arg3, sizeof(target_sigset_t), 0);
+ if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
+ goto efault;
host_to_target_sigset(p, &oldset);
unlock_user(p, arg3, sizeof(target_sigset_t));
}
sigset_t set;
ret = get_errno(sigpending(&set));
if (!is_error(ret)) {
- p = lock_user(arg1, sizeof(target_sigset_t), 0);
+ if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
+ goto efault;
host_to_target_old_sigset(p, &set);
unlock_user(p, arg1, sizeof(target_sigset_t));
}
sigset_t set;
ret = get_errno(sigpending(&set));
if (!is_error(ret)) {
- p = lock_user(arg1, sizeof(target_sigset_t), 0);
+ if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
+ goto efault;
host_to_target_sigset(p, &set);
unlock_user(p, arg1, sizeof(target_sigset_t));
}
case TARGET_NR_sigsuspend:
{
sigset_t set;
- p = lock_user(arg1, sizeof(target_sigset_t), 1);
+ if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
+ goto efault;
target_to_host_old_sigset(&set, p);
unlock_user(p, arg1, 0);
ret = get_errno(sigsuspend(&set));
case TARGET_NR_rt_sigsuspend:
{
sigset_t set;
- p = lock_user(arg1, sizeof(target_sigset_t), 1);
+ if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
+ goto efault;
target_to_host_sigset(&set, p);
unlock_user(p, arg1, 0);
ret = get_errno(sigsuspend(&set));
struct timespec uts, *puts;
siginfo_t uinfo;
- p = lock_user(arg1, sizeof(target_sigset_t), 1);
+ if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
+ goto efault;
target_to_host_sigset(&set, p);
unlock_user(p, arg1, 0);
if (arg3) {
}
ret = get_errno(sigtimedwait(&set, &uinfo, puts));
if (!is_error(ret) && arg2) {
- p = lock_user(arg2, sizeof(target_sigset_t), 0);
+ if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_sigset_t), 0)))
+ goto efault;
host_to_target_siginfo(p, &uinfo);
unlock_user(p, arg2, sizeof(target_sigset_t));
}
case TARGET_NR_rt_sigqueueinfo:
{
siginfo_t uinfo;
- p = lock_user(arg3, sizeof(target_sigset_t), 1);
+ if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
+ goto efault;
target_to_host_siginfo(&uinfo, p);
unlock_user(p, arg1, 0);
ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
ret = do_rt_sigreturn(cpu_env);
break;
case TARGET_NR_sethostname:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(sethostname(p, arg2));
unlock_user(p, arg1, 0);
break;
int resource = arg1;
struct target_rlimit *target_rlim;
struct rlimit rlim;
- lock_user_struct(target_rlim, arg2, 1);
+ if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
+ goto efault;
rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
rlim.rlim_max = tswapl(target_rlim->rlim_max);
unlock_user_struct(target_rlim, arg2, 0);
ret = get_errno(getrlimit(resource, &rlim));
if (!is_error(ret)) {
- lock_user_struct(target_rlim, arg2, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
+ goto efault;
rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
rlim.rlim_max = tswapl(target_rlim->rlim_max);
unlock_user_struct(target_rlim, arg2, 1);
abi_ulong inp, outp, exp, tvp;
long nsel;
- lock_user_struct(sel, arg1, 1);
+ if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
+ goto efault;
nsel = tswapl(sel->n);
inp = tswapl(sel->inp);
outp = tswapl(sel->outp);
void *p2;
p = lock_user_string(arg1);
p2 = lock_user_string(arg2);
- ret = get_errno(symlink(p, p2));
+ if (!p || !p2)
+ ret = -TARGET_EFAULT;
+ else
+ ret = get_errno(symlink(p, p2));
unlock_user(p2, arg2, 0);
unlock_user(p, arg1, 0);
}
break;
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
case TARGET_NR_symlinkat:
- if (!arg1 || !arg3) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
{
- void *p2 = NULL;
+ void *p2;
p = lock_user_string(arg1);
p2 = lock_user_string(arg3);
- if (!access_ok(VERIFY_READ, p, 1)
- || !access_ok(VERIFY_READ, p2, 1))
- /* Don't "goto fail" so that cleanup can happen. */
+ if (!p || !p2)
ret = -TARGET_EFAULT;
else
ret = get_errno(sys_symlinkat(p, arg2, p2));
- if (p2)
- unlock_user(p2, arg3, 0);
- if (p)
- unlock_user(p, arg1, 0);
+ unlock_user(p2, arg3, 0);
+ unlock_user(p, arg1, 0);
}
break;
#endif
{
void *p2;
p = lock_user_string(arg1);
- p2 = lock_user(arg2, arg3, 0);
- ret = get_errno(readlink(path(p), p2, arg3));
+ p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+ if (!p || !p2)
+ ret = -TARGET_EFAULT;
+ else
+ ret = get_errno(readlink(path(p), p2, arg3));
unlock_user(p2, arg2, ret);
unlock_user(p, arg1, 0);
}
break;
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
case TARGET_NR_readlinkat:
- if (!arg2 || !arg3) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
{
- void *p2 = NULL;
+ void *p2;
p = lock_user_string(arg2);
- p2 = lock_user(arg3, arg4, 0);
- if (!access_ok(VERIFY_READ, p, 1)
- || !access_ok(VERIFY_READ, p2, 1))
- /* Don't "goto fail" so that cleanup can happen. */
+ p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
+ if (!p || !p2)
ret = -TARGET_EFAULT;
else
ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
- if (p2)
- unlock_user(p2, arg3, ret);
- if (p)
- unlock_user(p, arg2, 0);
+ unlock_user(p2, arg3, ret);
+ unlock_user(p, arg2, 0);
}
break;
#endif
#endif
#ifdef TARGET_NR_swapon
case TARGET_NR_swapon:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(swapon(p, arg2));
unlock_user(p, arg1, 0);
break;
{
abi_ulong *v;
abi_ulong v1, v2, v3, v4, v5, v6;
- v = lock_user(arg1, 6 * sizeof(abi_ulong), 1);
+ if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
+ goto efault;
v1 = tswapl(v[0]);
v2 = tswapl(v[1]);
v3 = tswapl(v[2]);
break;
#endif
case TARGET_NR_truncate:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(truncate(p, arg2));
unlock_user(p, arg1, 0);
break;
break;
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
case TARGET_NR_fchmodat:
- if (!arg2) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
- p = lock_user_string(arg2);
- if (!access_ok(VERIFY_READ, p, 1))
- /* Don't "goto fail" so that cleanup can happen. */
- ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
- if (p)
- unlock_user(p, arg2, 0);
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
+ ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
+ unlock_user(p, arg2, 0);
break;
#endif
case TARGET_NR_getpriority:
goto unimplemented;
#endif
case TARGET_NR_statfs:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(statfs(path(p), &stfs));
unlock_user(p, arg1, 0);
convert_statfs:
if (!is_error(ret)) {
struct target_statfs *target_stfs;
- lock_user_struct(target_stfs, arg2, 0);
- /* ??? put_user is probably wrong. */
- put_user(stfs.f_type, &target_stfs->f_type);
- put_user(stfs.f_bsize, &target_stfs->f_bsize);
- put_user(stfs.f_blocks, &target_stfs->f_blocks);
- put_user(stfs.f_bfree, &target_stfs->f_bfree);
- put_user(stfs.f_bavail, &target_stfs->f_bavail);
- put_user(stfs.f_files, &target_stfs->f_files);
- put_user(stfs.f_ffree, &target_stfs->f_ffree);
- put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
- put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
- put_user(stfs.f_namelen, &target_stfs->f_namelen);
+ if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
+ goto efault;
+ __put_user(stfs.f_type, &target_stfs->f_type);
+ __put_user(stfs.f_bsize, &target_stfs->f_bsize);
+ __put_user(stfs.f_blocks, &target_stfs->f_blocks);
+ __put_user(stfs.f_bfree, &target_stfs->f_bfree);
+ __put_user(stfs.f_bavail, &target_stfs->f_bavail);
+ __put_user(stfs.f_files, &target_stfs->f_files);
+ __put_user(stfs.f_ffree, &target_stfs->f_ffree);
+ __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
+ __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
+ __put_user(stfs.f_namelen, &target_stfs->f_namelen);
unlock_user_struct(target_stfs, arg2, 1);
}
break;
goto convert_statfs;
#ifdef TARGET_NR_statfs64
case TARGET_NR_statfs64:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(statfs(path(p), &stfs));
unlock_user(p, arg1, 0);
convert_statfs64:
if (!is_error(ret)) {
struct target_statfs64 *target_stfs;
- lock_user_struct(target_stfs, arg3, 0);
- /* ??? put_user is probably wrong. */
- put_user(stfs.f_type, &target_stfs->f_type);
- put_user(stfs.f_bsize, &target_stfs->f_bsize);
- put_user(stfs.f_blocks, &target_stfs->f_blocks);
- put_user(stfs.f_bfree, &target_stfs->f_bfree);
- put_user(stfs.f_bavail, &target_stfs->f_bavail);
- put_user(stfs.f_files, &target_stfs->f_files);
- put_user(stfs.f_ffree, &target_stfs->f_ffree);
- put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
- put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
- put_user(stfs.f_namelen, &target_stfs->f_namelen);
- unlock_user_struct(target_stfs, arg3, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
+ goto efault;
+ __put_user(stfs.f_type, &target_stfs->f_type);
+ __put_user(stfs.f_bsize, &target_stfs->f_bsize);
+ __put_user(stfs.f_blocks, &target_stfs->f_blocks);
+ __put_user(stfs.f_bfree, &target_stfs->f_bfree);
+ __put_user(stfs.f_bavail, &target_stfs->f_bavail);
+ __put_user(stfs.f_files, &target_stfs->f_files);
+ __put_user(stfs.f_ffree, &target_stfs->f_ffree);
+ __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
+ __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
+ __put_user(stfs.f_namelen, &target_stfs->f_namelen);
+ unlock_user_struct(target_stfs, arg3, 1);
}
break;
case TARGET_NR_fstatfs64:
#endif
case TARGET_NR_syslog:
- p = lock_user_string(arg2);
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
unlock_user(p, arg2, 0);
break;
}
break;
case TARGET_NR_stat:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(stat(path(p), &st));
unlock_user(p, arg1, 0);
goto do_stat;
case TARGET_NR_lstat:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(lstat(path(p), &st));
unlock_user(p, arg1, 0);
goto do_stat;
if (!is_error(ret)) {
struct target_stat *target_st;
- lock_user_struct(target_st, arg2, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
+ goto efault;
#if defined(TARGET_MIPS) || (defined(TARGET_SPARC64) && !defined(TARGET_ABI32))
target_st->st_dev = tswap32(st.st_dev);
#else
break;
#ifdef TARGET_NR_swapoff
case TARGET_NR_swapoff:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(swapoff(p));
unlock_user(p, arg1, 0);
break;
ret = get_errno(sysinfo(&value));
if (!is_error(ret) && arg1)
{
- /* ??? __put_user is probably wrong. */
- lock_user_struct(target_value, arg1, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
+ goto efault;
__put_user(value.uptime, &target_value->uptime);
__put_user(value.loads[0], &target_value->loads[0]);
__put_user(value.loads[1], &target_value->loads[1]);
break;
#endif
case TARGET_NR_setdomainname:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(setdomainname(p, arg2));
unlock_user(p, arg1, 0);
break;
{
struct new_utsname * buf;
- lock_user_struct(buf, arg1, 0);
+ if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
+ goto efault;
ret = get_errno(sys_uname(buf));
if (!is_error(ret)) {
/* Overrite the native machine name with whatever is being
dirp = malloc(count);
if (!dirp) {
- ret = -TARGET_EFAULT;
+ ret = -TARGET_ENOMEM;
goto fail;
}
count1 = 0;
de = dirp;
- target_dirp = lock_user(arg2, count, 0);
+ if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
+ goto efault;
tde = target_dirp;
while (len > 0) {
reclen = de->d_reclen;
count1 += treclen;
}
ret = count1;
+ unlock_user(target_dirp, arg2, ret);
}
- unlock_user(target_dirp, arg2, ret);
free(dirp);
}
#else
struct dirent *dirp;
abi_long count = arg3;
- dirp = lock_user(arg2, count, 0);
+ if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
+ goto efault;
ret = get_errno(sys_getdents(arg1, dirp, count));
if (!is_error(ret)) {
struct dirent *de;
{
struct dirent64 *dirp;
abi_long count = arg3;
- dirp = lock_user(arg2, count, 0);
+ if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
+ goto efault;
ret = get_errno(sys_getdents64(arg1, dirp, count));
if (!is_error(ret)) {
struct dirent64 *de;
struct pollfd *pfd;
unsigned int i;
- target_pfd = lock_user(arg1, sizeof(struct target_pollfd) * nfds, 1);
+ target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
+ if (!target_pfd)
+ goto efault;
pfd = alloca(sizeof(struct pollfd) * nfds);
for(i = 0; i < nfds; i++) {
pfd[i].fd = tswap32(target_pfd[i].fd);
struct iovec *vec;
vec = alloca(count * sizeof(struct iovec));
- lock_iovec(vec, arg2, count, 0);
+ lock_iovec(VERIFY_WRITE, vec, arg2, count, 0);
ret = get_errno(readv(arg1, vec, count));
unlock_iovec(vec, arg2, count, 1);
}
struct iovec *vec;
vec = alloca(count * sizeof(struct iovec));
- lock_iovec(vec, arg2, count, 1);
+ lock_iovec(VERIFY_READ, vec, arg2, count, 1);
ret = get_errno(writev(arg1, vec, count));
unlock_iovec(vec, arg2, count, 0);
}
struct sched_param *target_schp;
struct sched_param schp;
- lock_user_struct(target_schp, arg2, 1);
+ if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
+ goto efault;
schp.sched_priority = tswap32(target_schp->sched_priority);
unlock_user_struct(target_schp, arg2, 0);
ret = get_errno(sched_setparam(arg1, &schp));
struct sched_param schp;
ret = get_errno(sched_getparam(arg1, &schp));
if (!is_error(ret)) {
- lock_user_struct(target_schp, arg2, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
+ goto efault;
target_schp->sched_priority = tswap32(schp.sched_priority);
unlock_user_struct(target_schp, arg2, 1);
}
{
struct sched_param *target_schp;
struct sched_param schp;
- lock_user_struct(target_schp, arg3, 1);
+ if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
+ goto efault;
schp.sched_priority = tswap32(target_schp->sched_priority);
unlock_user_struct(target_schp, arg3, 0);
ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
#ifdef TARGET_NR_pread
case TARGET_NR_pread:
page_unprotect_range(arg2, arg3);
- p = lock_user(arg2, arg3, 0);
+ if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
+ goto efault;
ret = get_errno(pread(arg1, p, arg3, arg4));
unlock_user(p, arg2, ret);
break;
case TARGET_NR_pwrite:
- p = lock_user(arg2, arg3, 1);
+ if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
+ goto efault;
ret = get_errno(pwrite(arg1, p, arg3, arg4));
unlock_user(p, arg2, 0);
break;
#endif
case TARGET_NR_getcwd:
- p = lock_user(arg1, arg2, 0);
+ if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
+ goto efault;
ret = get_errno(sys_getcwd1(p, arg2));
unlock_user(p, arg1, ret);
break;
case TARGET_NR_sigaltstack:
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
- ret = do_sigaltstack((struct target_sigaltstack *)arg1,
- (struct target_sigaltstack *)arg2,
- get_sp_from_cpustate((CPUState *)cpu_env));
+ ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
break;
#else
goto unimplemented;
ret = get_errno(getrlimit(arg1, &rlim));
if (!is_error(ret)) {
struct target_rlimit *target_rlim;
- lock_user_struct(target_rlim, arg2, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
+ goto efault;
target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
target_rlim->rlim_max = tswapl(rlim.rlim_max);
unlock_user_struct(target_rlim, arg2, 1);
#endif
#ifdef TARGET_NR_truncate64
case TARGET_NR_truncate64:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
unlock_user(p, arg1, 0);
break;
#endif
#ifdef TARGET_NR_stat64
case TARGET_NR_stat64:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(stat(path(p), &st));
unlock_user(p, arg1, 0);
goto do_stat64;
#endif
#ifdef TARGET_NR_lstat64
case TARGET_NR_lstat64:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(lstat(path(p), &st));
unlock_user(p, arg1, 0);
goto do_stat64;
#ifdef TARGET_ARM
if (((CPUARMState *)cpu_env)->eabi) {
struct target_eabi_stat64 *target_st;
- lock_user_struct(target_st, arg2, 1);
+
+ if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
+ goto efault;
memset(target_st, 0, sizeof(struct target_eabi_stat64));
- /* put_user is probably wrong. */
- put_user(st.st_dev, &target_st->st_dev);
- put_user(st.st_ino, &target_st->st_ino);
+ __put_user(st.st_dev, &target_st->st_dev);
+ __put_user(st.st_ino, &target_st->st_ino);
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
- put_user(st.st_ino, &target_st->__st_ino);
-#endif
- put_user(st.st_mode, &target_st->st_mode);
- put_user(st.st_nlink, &target_st->st_nlink);
- put_user(st.st_uid, &target_st->st_uid);
- put_user(st.st_gid, &target_st->st_gid);
- put_user(st.st_rdev, &target_st->st_rdev);
- /* XXX: better use of kernel struct */
- put_user(st.st_size, &target_st->st_size);
- put_user(st.st_blksize, &target_st->st_blksize);
- put_user(st.st_blocks, &target_st->st_blocks);
- put_user(st.st_atime, &target_st->target_st_atime);
- put_user(st.st_mtime, &target_st->target_st_mtime);
- put_user(st.st_ctime, &target_st->target_st_ctime);
- unlock_user_struct(target_st, arg2, 0);
+ __put_user(st.st_ino, &target_st->__st_ino);
+#endif
+ __put_user(st.st_mode, &target_st->st_mode);
+ __put_user(st.st_nlink, &target_st->st_nlink);
+ __put_user(st.st_uid, &target_st->st_uid);
+ __put_user(st.st_gid, &target_st->st_gid);
+ __put_user(st.st_rdev, &target_st->st_rdev);
+ __put_user(st.st_size, &target_st->st_size);
+ __put_user(st.st_blksize, &target_st->st_blksize);
+ __put_user(st.st_blocks, &target_st->st_blocks);
+ __put_user(st.st_atime, &target_st->target_st_atime);
+ __put_user(st.st_mtime, &target_st->target_st_mtime);
+ __put_user(st.st_ctime, &target_st->target_st_ctime);
+ unlock_user_struct(target_st, arg2, 1);
} else
#endif
{
struct target_stat64 *target_st;
- lock_user_struct(target_st, arg2, 1);
+
+ if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
+ goto efault;
memset(target_st, 0, sizeof(struct target_stat64));
- /* ??? put_user is probably wrong. */
- put_user(st.st_dev, &target_st->st_dev);
- put_user(st.st_ino, &target_st->st_ino);
+ __put_user(st.st_dev, &target_st->st_dev);
+ __put_user(st.st_ino, &target_st->st_ino);
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
- put_user(st.st_ino, &target_st->__st_ino);
+ __put_user(st.st_ino, &target_st->__st_ino);
#endif
- put_user(st.st_mode, &target_st->st_mode);
- put_user(st.st_nlink, &target_st->st_nlink);
- put_user(st.st_uid, &target_st->st_uid);
- put_user(st.st_gid, &target_st->st_gid);
- put_user(st.st_rdev, &target_st->st_rdev);
+ __put_user(st.st_mode, &target_st->st_mode);
+ __put_user(st.st_nlink, &target_st->st_nlink);
+ __put_user(st.st_uid, &target_st->st_uid);
+ __put_user(st.st_gid, &target_st->st_gid);
+ __put_user(st.st_rdev, &target_st->st_rdev);
/* XXX: better use of kernel struct */
- put_user(st.st_size, &target_st->st_size);
- put_user(st.st_blksize, &target_st->st_blksize);
- put_user(st.st_blocks, &target_st->st_blocks);
- put_user(st.st_atime, &target_st->target_st_atime);
- put_user(st.st_mtime, &target_st->target_st_mtime);
- put_user(st.st_ctime, &target_st->target_st_ctime);
- unlock_user_struct(target_st, arg2, 0);
+ __put_user(st.st_size, &target_st->st_size);
+ __put_user(st.st_blksize, &target_st->st_blksize);
+ __put_user(st.st_blocks, &target_st->st_blocks);
+ __put_user(st.st_atime, &target_st->target_st_atime);
+ __put_user(st.st_mtime, &target_st->target_st_mtime);
+ __put_user(st.st_ctime, &target_st->target_st_ctime);
+ unlock_user_struct(target_st, arg2, 1);
}
}
}
#endif
#ifdef USE_UID16
case TARGET_NR_lchown:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
unlock_user(p, arg1, 0);
break;
grouplist = alloca(gidsetsize * sizeof(gid_t));
ret = get_errno(getgroups(gidsetsize, grouplist));
if (!is_error(ret)) {
- target_grouplist = lock_user(arg2, gidsetsize * 2, 0);
+ target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
+ if (!target_grouplist)
+ goto efault;
for(i = 0;i < gidsetsize; i++)
target_grouplist[i] = tswap16(grouplist[i]);
unlock_user(target_grouplist, arg2, gidsetsize * 2);
int i;
grouplist = alloca(gidsetsize * sizeof(gid_t));
- target_grouplist = lock_user(arg2, gidsetsize * 2, 1);
+ target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
+ if (!target_grouplist) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
for(i = 0;i < gidsetsize; i++)
grouplist[i] = tswap16(target_grouplist[i]);
unlock_user(target_grouplist, arg2, 0);
break;
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
case TARGET_NR_fchownat:
- if (!arg2) {
- ret = -TARGET_EFAULT;
- goto fail;
- }
- p = lock_user_string(arg2);
- if (!access_ok(VERIFY_READ, p, 1))
- /* Don't "goto fail" so that cleanup can happen. */
- ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
- if (p)
- unlock_user(p, arg2, 0);
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
+ ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
+ unlock_user(p, arg2, 0);
break;
#endif
#ifdef TARGET_NR_setresuid
break;
#endif
case TARGET_NR_chown:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
unlock_user(p, arg1, 0);
break;
#ifdef TARGET_NR_lchown32
case TARGET_NR_lchown32:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(lchown(p, arg2, arg3));
unlock_user(p, arg1, 0);
break;
grouplist = alloca(gidsetsize * sizeof(gid_t));
ret = get_errno(getgroups(gidsetsize, grouplist));
if (!is_error(ret)) {
- target_grouplist = lock_user(arg2, gidsetsize * 4, 0);
+ target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
+ if (!target_grouplist) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
for(i = 0;i < gidsetsize; i++)
target_grouplist[i] = tswap32(grouplist[i]);
unlock_user(target_grouplist, arg2, gidsetsize * 4);
int i;
grouplist = alloca(gidsetsize * sizeof(gid_t));
- target_grouplist = lock_user(arg2, gidsetsize * 4, 1);
+ target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
+ if (!target_grouplist) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
for(i = 0;i < gidsetsize; i++)
grouplist[i] = tswap32(target_grouplist[i]);
unlock_user(target_grouplist, arg2, 0);
#endif
#ifdef TARGET_NR_chown32
case TARGET_NR_chown32:
- p = lock_user_string(arg1);
+ if (!(p = lock_user_string(arg1)))
+ goto efault;
ret = get_errno(chown(p, arg2, arg3));
unlock_user(p, arg1, 0);
break;
case TARGET_F_GETLK64:
#ifdef TARGET_ARM
if (((CPUARMState *)cpu_env)->eabi) {
- lock_user_struct(target_efl, arg3, 1);
+ if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
fl.l_type = tswap16(target_efl->l_type);
fl.l_whence = tswap16(target_efl->l_whence);
fl.l_start = tswap64(target_efl->l_start);
} else
#endif
{
- lock_user_struct(target_fl, arg3, 1);
+ if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
fl.l_type = tswap16(target_fl->l_type);
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswap64(target_fl->l_start);
if (ret == 0) {
#ifdef TARGET_ARM
if (((CPUARMState *)cpu_env)->eabi) {
- lock_user_struct(target_efl, arg3, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
target_efl->l_type = tswap16(fl.l_type);
target_efl->l_whence = tswap16(fl.l_whence);
target_efl->l_start = tswap64(fl.l_start);
} else
#endif
{
- lock_user_struct(target_fl, arg3, 0);
+ if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
target_fl->l_type = tswap16(fl.l_type);
target_fl->l_whence = tswap16(fl.l_whence);
target_fl->l_start = tswap64(fl.l_start);
case TARGET_F_SETLKW64:
#ifdef TARGET_ARM
if (((CPUARMState *)cpu_env)->eabi) {
- lock_user_struct(target_efl, arg3, 1);
+ if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
fl.l_type = tswap16(target_efl->l_type);
fl.l_whence = tswap16(target_efl->l_whence);
fl.l_start = tswap64(target_efl->l_start);
} else
#endif
{
- lock_user_struct(target_fl, arg3, 1);
+ if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) {
+ ret = -TARGET_EFAULT;
+ goto fail;
+ }
fl.l_type = tswap16(target_fl->l_type);
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswap64(target_fl->l_start);
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
case TARGET_NR_set_tid_address:
- ret = get_errno(set_tid_address((int *) arg1));
- break;
+ ret = get_errno(set_tid_address((int *)g2h(arg1)));
+ break;
#endif
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
if (!arg2)
ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
else {
- p = lock_user_string(arg2);
- if (!access_ok(VERIFY_READ, p, 1))
- /* Don't "goto fail" so that cleanup can happen. */
+ if (!(p = lock_user_string(arg2))) {
ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
- if (p)
- unlock_user(p, arg2, 0);
+ goto fail;
+ }
+ ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
+ unlock_user(p, arg2, 0);
}
}
break;
ret = -TARGET_ENOSYS;
break;
}
- fail:
+fail:
#ifdef DEBUG
gemu_log(" = %ld\n", ret);
#endif
if(do_strace)
print_syscall_ret(num, ret);
return ret;
+efault:
+ ret = -TARGET_EFAULT;
+ goto fail;
}