svn commit: r272132 - in head/sys: compat/freebsd32 kern sys

Konstantin Belousov kib at FreeBSD.org
Thu Sep 25 21:07:21 UTC 2014


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);


More information about the svn-src-head mailing list