qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] RFC: [10/11] EFAULT patch
@ 2007-09-19  1:35 Stuart Anderson
  0 siblings, 0 replies; only message in thread
From: Stuart Anderson @ 2007-09-19  1:35 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 597 bytes --]


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                               anderson@netsweng.com
Network & Software Engineering                   http://www.netsweng.com/
1024D/37A79149:                                  0791 D3B8 9A4C 2CDC A31F
                                                  BD03 0A62 E534 37A7 9149

[-- Attachment #2: efault patch 10 off 11 --]
[-- Type: TEXT/PLAIN, Size: 11530 bytes --]

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;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-09-19  1:35 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-19  1:35 [Qemu-devel] RFC: [10/11] EFAULT patch Stuart Anderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).