This part contains the rest of the updates to do_syscall() that contain
the changes to the new API for several systcalls, including utime(),
sigaction(), rt_sigaction(), rt_sigpending(), sigsuspend(),
rt_sigtimedwait(), rt_sigqueueinfo(), stat() and stat64().
Stuart
Stuart R. Anderson [EMAIL PROTECTED]
Network & Software Engineering http://www.netsweng.com/
1024D/37A79149: 0791 D3B8 9A4C 2CDC A31F
BD03 0A62 E534 37A7 9149
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;