Index: qemu/linux-user/syscall.c =================================================================== --- qemu.orig/linux-user/syscall.c 2007-09-17 01:09:25.000000000 -0400 +++ qemu/linux-user/syscall.c 2007-09-17 01:12:47.000000000 -0400 @@ -2687,12 +2687,11 @@ case TARGET_NR_utime: { struct utimbuf tbuf, *host_tbuf; - struct target_utimbuf *target_tbuf; + struct target_utimbuf *target_tbuf = (struct target_utimbuf *)arg2; if (arg2) { - lock_user_struct(target_tbuf, arg2, 1); + if( !access_ok(VERIFY_READ,target_tbuf,sizeof(struct target_utimbuf)) ) return -EFAULT; tbuf.actime = tswapl(target_tbuf->actime); tbuf.modtime = tswapl(target_tbuf->modtime); - unlock_user_struct(target_tbuf, arg2, 0); host_tbuf = &tbuf; } else { host_tbuf = NULL; @@ -2878,37 +2877,35 @@ case TARGET_NR_sigaction: { #if !defined(TARGET_MIPS) - struct target_old_sigaction *old_act; + struct target_old_sigaction *old_act = (struct target_old_sigaction *)arg2; struct target_sigaction act, oact, *pact; if (arg2) { - lock_user_struct(old_act, arg2, 1); + if( !access_ok(VERIFY_READ,old_act,sizeof(*old_act)) ) return -EFAULT; act._sa_handler = old_act->_sa_handler; target_siginitset(&act.sa_mask, old_act->sa_mask); act.sa_flags = old_act->sa_flags; act.sa_restorer = old_act->sa_restorer; - unlock_user_struct(old_act, arg2, 0); pact = &act; } else { pact = NULL; } ret = get_errno(do_sigaction(arg1, pact, &oact)); if (!is_error(ret) && arg3) { - lock_user_struct(old_act, arg3, 0); + old_act = (struct target_old_sigaction *)arg3; + if( !access_ok(VERIFY_WRITE,old_act,sizeof(*old_act)) ) return -EFAULT; old_act->_sa_handler = oact._sa_handler; old_act->sa_mask = oact.sa_mask.sig[0]; old_act->sa_flags = oact.sa_flags; old_act->sa_restorer = oact.sa_restorer; - unlock_user_struct(old_act, arg3, 1); } #else struct target_sigaction act, oact, *pact, *old_act; if (arg2) { - lock_user_struct(old_act, arg2, 1); + if( !access_ok(VERIFY_READ,old_act,sizeof(*old_act)) ) return -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; - unlock_user_struct(old_act, arg2, 0); pact = &act; } else { pact = NULL; @@ -2917,14 +2914,14 @@ ret = get_errno(do_sigaction(arg1, pact, &oact)); if (!is_error(ret) && arg3) { - lock_user_struct(old_act, arg3, 0); + old_act = (struct target_old_sigaction *)arg3; + if( !access_ok(VERIFY_WRITE,old_act,sizeof(*old_act)) ) return -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]; old_act->sa_mask.sig[1] = 0; old_act->sa_mask.sig[2] = 0; old_act->sa_mask.sig[3] = 0; - unlock_user_struct(old_act, arg3, 1); } #endif } @@ -2932,22 +2929,20 @@ #endif case TARGET_NR_rt_sigaction: { - struct target_sigaction *act; - struct target_sigaction *oact; + struct target_sigaction *act = (struct target_sigaction *)arg2; + struct target_sigaction *oact = (struct target_sigaction *)arg3; - if (arg2) - lock_user_struct(act, arg2, 1); + if (arg2) { + if( !access_ok(VERIFY_READ,act,sizeof(*act)) ) return -EFAULT; + } else act = NULL; - if (arg3) - lock_user_struct(oact, arg3, 0); + if (arg3) { + if( !access_ok(VERIFY_WRITE,oact,sizeof(*oact)) ) return -EFAULT; + } else oact = NULL; ret = get_errno(do_sigaction(arg1, act, oact)); - if (arg2) - unlock_user_struct(act, arg2, 0); - if (arg3) - unlock_user_struct(oact, arg3, 1); } break; #ifdef TARGET_NR_sgetmask /* not on alpha */ @@ -3064,22 +3059,22 @@ #endif case TARGET_NR_rt_sigpending: { + target_sigset_t *tsig = (target_sigset_t *)arg1; sigset_t set; ret = get_errno(sigpending(&set)); if (!is_error(ret)) { - p = lock_user(arg1, sizeof(target_sigset_t), 0); - host_to_target_sigset(p, &set); - unlock_user(p, arg1, sizeof(target_sigset_t)); + if( !access_ok(VERIFY_WRITE,tsig,sizeof(target_sigset_t)) ) return -EFAULT; + host_to_target_sigset(tsig, &set); } } break; #ifdef TARGET_NR_sigsuspend case TARGET_NR_sigsuspend: { + target_sigset_t *tsig = (target_sigset_t *)arg1; sigset_t set; - p = lock_user(arg1, sizeof(target_sigset_t), 1); - target_to_host_old_sigset(&set, p); - unlock_user(p, arg1, 0); + if( !access_ok(VERIFY_READ,tsig,sizeof(target_sigset_t)) ) return -EFAULT; + target_to_host_sigset(&set, tsig); ret = get_errno(sigsuspend(&set)); } break; @@ -3095,33 +3090,33 @@ break; case TARGET_NR_rt_sigtimedwait: { + target_sigset_t *tsig = (target_sigset_t *)arg1; sigset_t set; struct timespec uts, *puts; siginfo_t uinfo; - p = lock_user(arg1, sizeof(target_sigset_t), 1); - target_to_host_sigset(&set, p); - unlock_user(p, arg1, 0); + if( !access_ok(VERIFY_READ,tsig,sizeof(target_sigset_t)) ) return -EFAULT; + target_to_host_sigset(&set, tsig); if (arg3) { puts = &uts; - copy_from_user_timespec(puts, (struct target_timespec *)arg3); + if( copy_from_user_timespec(puts, (struct target_timespec *)arg3) ) return -EFAULT; } else { puts = NULL; } ret = get_errno(sigtimedwait(&set, &uinfo, puts)); if (!is_error(ret) && arg2) { - p = lock_user(arg2, sizeof(target_sigset_t), 0); - host_to_target_siginfo(p, &uinfo); - unlock_user(p, arg2, sizeof(target_sigset_t)); + tsig = (target_sigset_t *)arg2; + if( !access_ok(VERIFY_WRITE,tsig,sizeof(target_sigset_t)) ) return -EFAULT; + host_to_target_siginfo(tsig, &uinfo); } } break; case TARGET_NR_rt_sigqueueinfo: { + target_sigset_t *tsig = (target_sigset_t *)arg3; siginfo_t uinfo; - p = lock_user(arg3, sizeof(target_sigset_t), 1); - target_to_host_siginfo(&uinfo, p); - unlock_user(p, arg1, 0); + if( !access_ok(VERIFY_READ,tsig,sizeof(target_siginfo_t)) ) return -EFAULT; + target_to_host_siginfo(&uinfo, tsig); ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); } break; @@ -3183,14 +3178,14 @@ struct timeval tv; ret = get_errno(gettimeofday(&tv, NULL)); if (!is_error(ret)) { - copy_to_user_timeval(arg1, &tv); + if( copy_to_user_timeval((struct target_timeval *)arg1, &tv) ) return -EFAULT; } } break; case TARGET_NR_settimeofday: { struct timeval tv; - copy_from_user_timeval(&tv, arg1); + if( copy_from_user_timeval(&tv, (struct target_timeval *)arg1) ) return -EFAULT; ret = get_errno(settimeofday(&tv, NULL)); } break; @@ -3415,7 +3410,7 @@ #endif #ifdef TARGET_NR_accept case TARGET_NR_accept: - ret = do_accept(arg1, arg2, arg3); + ret = do_accept(arg1, arg2, (socklen_t *)arg3); break; #endif #ifdef TARGET_NR_bind @@ -3430,17 +3425,17 @@ #endif #ifdef TARGET_NR_getpeername case TARGET_NR_getpeername: - ret = do_getpeername(arg1, arg2, arg3); + ret = do_getpeername(arg1, arg2, (socklen_t *)arg3); break; #endif #ifdef TARGET_NR_getsockname case TARGET_NR_getsockname: - ret = do_getsockname(arg1, arg2, arg3); + ret = do_getsockname(arg1, arg2, (socklen_t *)arg3); break; #endif #ifdef TARGET_NR_getsockopt case TARGET_NR_getsockopt: - ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5); + ret = do_getsockopt(arg1, arg2, arg3, arg4, (socklen_t *)arg5); break; #endif #ifdef TARGET_NR_listen @@ -3546,11 +3541,13 @@ break; case TARGET_NR_stat: p = lock_user_string(arg1); + if( !access_ok(VERIFY_READ,p,1) ) return -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( !access_ok(VERIFY_READ,p,1) ) return -EFAULT; ret = get_errno(lstat(path(p), &st)); unlock_user(p, arg1, 0); goto do_stat; @@ -3559,9 +3556,9 @@ ret = get_errno(fstat(arg1, &st)); do_stat: if (!is_error(ret)) { - struct target_stat *target_st; + struct target_stat *target_st = (struct target_stat *)arg2; - lock_user_struct(target_st, arg2, 0); + if( !access_ok(VERIFY_WRITE,target_st,sizeof(*target_st)) ) return -EFAULT; #if defined(TARGET_MIPS) || defined(TARGET_SPARC64) target_st->st_dev = tswap32(st.st_dev); #else @@ -3598,7 +3595,6 @@ target_st->target_st_atime = tswapl(st.st_atime); target_st->target_st_mtime = tswapl(st.st_mtime); target_st->target_st_ctime = tswapl(st.st_ctime); - unlock_user_struct(target_st, arg2, 1); } } break; @@ -3627,7 +3623,7 @@ int status; target_long status_ptr = arg2; struct rusage rusage, *rusage_ptr; - target_ulong target_rusage = arg4; + struct target_rusage *target_rusage = (struct target_rusage *)arg4; if (target_rusage) rusage_ptr = &rusage; else @@ -4107,6 +4103,7 @@ #ifdef TARGET_NR_stat64 case TARGET_NR_stat64: p = lock_user_string(arg1); + if( !access_ok(VERIFY_READ,p,1) ) return -EFAULT; ret = get_errno(stat(path(p), &st)); unlock_user(p, arg1, 0); goto do_stat64; @@ -4114,6 +4111,7 @@ #ifdef TARGET_NR_lstat64 case TARGET_NR_lstat64: p = lock_user_string(arg1); + if( !access_ok(VERIFY_READ,p,1) ) return -EFAULT; ret = get_errno(lstat(path(p), &st)); unlock_user(p, arg1, 0); goto do_stat64;