Author: kib
Date: Thu Sep 25 21:07:19 2014
New Revision: 272132
URL: http://svnweb.freebsd.org/changeset/base/272132

Log:
  Fix fcntl(2) compat32 after r270691.  The copyin and copyout of the
  struct flock are done in the sys_fcntl(), which mean that compat32 used
  direct access to userland pointers.
  
  Move code from sys_fcntl() to new wrapper, kern_fcntl_freebsd(), which
  performs neccessary userland memory accesses, and use it from both
  native and compat32 fcntl syscalls.
  
  Reported by:  jhibbits
  Sponsored by: The FreeBSD Foundation
  MFC after:    3 days

Modified:
  head/sys/compat/freebsd32/freebsd32_misc.c
  head/sys/kern/kern_descrip.c
  head/sys/sys/syscallsubr.h

Modified: head/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c  Thu Sep 25 20:56:05 2014        
(r272131)
+++ head/sys/compat/freebsd32/freebsd32_misc.c  Thu Sep 25 21:07:19 2014        
(r272132)
@@ -2984,7 +2984,7 @@ freebsd32_procctl(struct thread *td, str
 int
 freebsd32_fcntl(struct thread *td, struct freebsd32_fcntl_args *uap)
 {
-       intptr_t tmp;
+       long tmp;
 
        switch (uap->cmd) {
        /*
@@ -3003,5 +3003,5 @@ freebsd32_fcntl(struct thread *td, struc
                tmp = uap->arg;
                break;
        }
-       return (kern_fcntl(td, uap->fd, uap->cmd, tmp));
+       return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp));
 }

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c        Thu Sep 25 20:56:05 2014        
(r272131)
+++ head/sys/kern/kern_descrip.c        Thu Sep 25 21:07:19 2014        
(r272132)
@@ -378,22 +378,27 @@ struct fcntl_args {
 int
 sys_fcntl(struct thread *td, struct fcntl_args *uap)
 {
+
+       return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, uap->arg));
+}
+
+int
+kern_fcntl_freebsd(struct thread *td, int fd, int cmd, long arg)
+{
        struct flock fl;
        struct __oflock ofl;
-       intptr_t arg;
+       intptr_t arg1;
        int error;
-       int cmd;
 
        error = 0;
-       cmd = uap->cmd;
-       switch (uap->cmd) {
+       switch (cmd) {
        case F_OGETLK:
        case F_OSETLK:
        case F_OSETLKW:
                /*
                 * Convert old flock structure to new.
                 */
-               error = copyin((void *)(intptr_t)uap->arg, &ofl, sizeof(ofl));
+               error = copyin((void *)(intptr_t)arg, &ofl, sizeof(ofl));
                fl.l_start = ofl.l_start;
                fl.l_len = ofl.l_len;
                fl.l_pid = ofl.l_pid;
@@ -401,7 +406,7 @@ sys_fcntl(struct thread *td, struct fcnt
                fl.l_whence = ofl.l_whence;
                fl.l_sysid = 0;
 
-               switch (uap->cmd) {
+               switch (cmd) {
                case F_OGETLK:
                    cmd = F_GETLK;
                    break;
@@ -412,33 +417,33 @@ sys_fcntl(struct thread *td, struct fcnt
                    cmd = F_SETLKW;
                    break;
                }
-               arg = (intptr_t)&fl;
+               arg1 = (intptr_t)&fl;
                break;
         case F_GETLK:
         case F_SETLK:
         case F_SETLKW:
        case F_SETLK_REMOTE:
-                error = copyin((void *)(intptr_t)uap->arg, &fl, sizeof(fl));
-                arg = (intptr_t)&fl;
+                error = copyin((void *)(intptr_t)arg, &fl, sizeof(fl));
+                arg1 = (intptr_t)&fl;
                 break;
        default:
-               arg = uap->arg;
+               arg1 = arg;
                break;
        }
        if (error)
                return (error);
-       error = kern_fcntl(td, uap->fd, cmd, arg);
+       error = kern_fcntl(td, fd, cmd, arg1);
        if (error)
                return (error);
-       if (uap->cmd == F_OGETLK) {
+       if (cmd == F_OGETLK) {
                ofl.l_start = fl.l_start;
                ofl.l_len = fl.l_len;
                ofl.l_pid = fl.l_pid;
                ofl.l_type = fl.l_type;
                ofl.l_whence = fl.l_whence;
-               error = copyout(&ofl, (void *)(intptr_t)uap->arg, sizeof(ofl));
-       } else if (uap->cmd == F_GETLK) {
-               error = copyout(&fl, (void *)(intptr_t)uap->arg, sizeof(fl));
+               error = copyout(&ofl, (void *)(intptr_t)arg, sizeof(ofl));
+       } else if (cmd == F_GETLK) {
+               error = copyout(&fl, (void *)(intptr_t)arg, sizeof(fl));
        }
        return (error);
 }

Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h  Thu Sep 25 20:56:05 2014        (r272131)
+++ head/sys/sys/syscallsubr.h  Thu Sep 25 21:07:19 2014        (r272132)
@@ -97,6 +97,7 @@ int   kern_fchmodat(struct thread *td, int
 int    kern_fchownat(struct thread *td, int fd, char *path,
            enum uio_seg pathseg, int uid, int gid, int flag);
 int    kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg);
+int    kern_fcntl_freebsd(struct thread *td, int fd, int cmd, long arg);
 int    kern_fhstat(struct thread *td, fhandle_t fh, struct stat *buf);
 int    kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf);
 int    kern_fstat(struct thread *td, int fd, struct stat *sbp);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to