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;

Reply via email to