Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Oct 2018 17:59:25 +0000 (UTC)
From:      Brooks Davis <brooks@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r339779 - in head/sys: compat/freebsd32 fs/devfs kern sys
Message-ID:  <201810261759.w9QHxPqE093372@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: brooks
Date: Fri Oct 26 17:59:25 2018
New Revision: 339779
URL: https://svnweb.freebsd.org/changeset/base/339779

Log:
  Move 32-bit compat support for FIODGNAME to the right place.
  
  ioctl(2) commands only have meaning in the context of a file descriptor
  so translating them in the syscall layer is incorrect.
  
  The new handler users an accessor to retrieve/construct a pointer from
  the last member of the passed structure and relies on type punning to
  access the other member which requires no translation.
  
  Unlike r339174 this change supports both places FIODGNAME is handled.
  
  Reviewed by:	kib
  Obtained from:	CheriBSD
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D17475

Modified:
  head/sys/compat/freebsd32/freebsd32_ioctl.c
  head/sys/compat/freebsd32/freebsd32_ioctl.h
  head/sys/fs/devfs/devfs_vnops.c
  head/sys/kern/tty_pts.c
  head/sys/sys/filio.h

Modified: head/sys/compat/freebsd32/freebsd32_ioctl.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_ioctl.c	Fri Oct 26 16:34:19 2018	(r339778)
+++ head/sys/compat/freebsd32/freebsd32_ioctl.c	Fri Oct 26 17:59:25 2018	(r339779)
@@ -59,22 +59,6 @@ __FBSDID("$FreeBSD$");
 CTASSERT(sizeof(struct mem_range_op32) == 12);
 
 static int
-freebsd32_ioctl_fiodgname(struct thread *td,
-    struct freebsd32_ioctl_args *uap, struct file *fp)
-{
-	struct fiodgname_arg fgn;
-	struct fiodgname_arg32 fgn32;
-	int error;
-
-	if ((error = copyin(uap->data, &fgn32, sizeof fgn32)) != 0)
-		return (error);
-	CP(fgn32, fgn, len);
-	PTRIN_CP(fgn32, fgn, buf);
-	error = fo_ioctl(fp, FIODGNAME, (caddr_t)&fgn, td->td_ucred, td);
-	return (error);
-}
-
-static int
 freebsd32_ioctl_memrange(struct thread *td,
     struct freebsd32_ioctl_args *uap, struct file *fp)
 {
@@ -237,10 +221,6 @@ freebsd32_ioctl(struct thread *td, struct freebsd32_io
 	}
 
 	switch (uap->com) {
-	case FIODGNAME_32:
-		error = freebsd32_ioctl_fiodgname(td, uap, fp);
-		break;
-
 	case MEMRANGE_GET32:	/* FALLTHROUGH */
 	case MEMRANGE_SET32:
 		error = freebsd32_ioctl_memrange(td, uap, fp);

Modified: head/sys/compat/freebsd32/freebsd32_ioctl.h
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_ioctl.h	Fri Oct 26 16:34:19 2018	(r339778)
+++ head/sys/compat/freebsd32/freebsd32_ioctl.h	Fri Oct 26 17:59:25 2018	(r339779)
@@ -38,11 +38,6 @@
 
 typedef __uint32_t caddr_t32;
 
-struct fiodgname_arg32 {
-	int		len;
-	caddr_t32	buf;
-};
-
 struct mem_range_op32
 {
 	caddr_t32	mo_desc;
@@ -60,7 +55,6 @@ struct pci_bar_mmap32 {
 	int		pbm_memattr;
 };
 
-#define	FIODGNAME_32	_IOW('f', 120, struct fiodgname_arg32)
 #define	MEMRANGE_GET32	_IOWR('m', 50, struct mem_range_op32)
 #define	MEMRANGE_SET32	_IOW('m', 51, struct mem_range_op32)
 #define	SG_IO_32	_IOWR(SGIOC, 0x85, struct sg_io_hdr32)

Modified: head/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- head/sys/fs/devfs/devfs_vnops.c	Fri Oct 26 16:34:19 2018	(r339778)
+++ head/sys/fs/devfs/devfs_vnops.c	Fri Oct 26 17:59:25 2018	(r339779)
@@ -767,6 +767,29 @@ devfs_ioctl_f(struct file *fp, u_long com, void *data,
 	return (error);
 }
 
+void *
+fiodgname_buf_get_ptr(void *fgnp, u_long com)
+{
+	union {
+		struct fiodgname_arg	fgn;
+#ifdef COMPAT_FREEBSD32
+		struct fiodgname_arg32	fgn32;
+#endif
+	} *fgnup;
+
+	fgnup = fgnp;
+	switch (com) {
+	case FIODGNAME:
+		return (fgnup->fgn.buf);
+#ifdef COMPAT_FREEBSD32
+	case FIODGNAME_32:
+		return ((void *)(uintptr_t)fgnup->fgn32.buf);
+#endif
+	default:
+		panic("Unhandled ioctl command %ld", com);
+	}
+}
+
 static int
 devfs_ioctl(struct vop_ioctl_args *ap)
 {
@@ -789,24 +812,27 @@ devfs_ioctl(struct vop_ioctl_args *ap)
 	KASSERT(dev->si_refcount > 0,
 	    ("devfs: un-referenced struct cdev *(%s)", devtoname(dev)));
 
-	if (com == FIODTYPE) {
+	switch (com) {
+	case FIODTYPE:
 		*(int *)ap->a_data = dsw->d_flags & D_TYPEMASK;
 		error = 0;
-		goto out;
-	} else if (com == FIODGNAME) {
+		break;
+	case FIODGNAME:
+#ifdef	COMPAT_FREEBSD32
+	case FIODGNAME_32:
+#endif
 		fgn = ap->a_data;
 		p = devtoname(dev);
 		i = strlen(p) + 1;
 		if (i > fgn->len)
 			error = EINVAL;
 		else
-			error = copyout(p, fgn->buf, i);
-		goto out;
+			error = copyout(p, fiodgname_buf_get_ptr(fgn, com), i);
+		break;
+	default:
+		error = dsw->d_ioctl(dev, com, ap->a_data, ap->a_fflag, td);
 	}
 
-	error = dsw->d_ioctl(dev, com, ap->a_data, ap->a_fflag, td);
-
-out:
 	dev_relthread(dev, ref);
 	if (error == ENOIOCTL)
 		error = ENOTTY;

Modified: head/sys/kern/tty_pts.c
==============================================================================
--- head/sys/kern/tty_pts.c	Fri Oct 26 16:34:19 2018	(r339778)
+++ head/sys/kern/tty_pts.c	Fri Oct 26 17:59:25 2018	(r339779)
@@ -281,7 +281,11 @@ ptsdev_ioctl(struct file *fp, u_long cmd, void *data,
 		}
 		tty_unlock(tp);
 		return (0);
-	case FIODGNAME: {
+	case FIODGNAME:
+#ifdef COMPAT_FREEBSD32
+	case FIODGNAME_32:
+#endif
+	{
 		struct fiodgname_arg *fgn;
 		const char *p;
 		int i;
@@ -292,7 +296,7 @@ ptsdev_ioctl(struct file *fp, u_long cmd, void *data,
 		i = strlen(p) + 1;
 		if (i > fgn->len)
 			return (EINVAL);
-		return copyout(p, fgn->buf, i);
+		return (copyout(p, fiodgname_buf_get_ptr(fgn, cmd), i));
 	}
 
 	/*

Modified: head/sys/sys/filio.h
==============================================================================
--- head/sys/sys/filio.h	Fri Oct 26 16:34:19 2018	(r339778)
+++ head/sys/sys/filio.h	Fri Oct 26 17:59:25 2018	(r339779)
@@ -63,4 +63,16 @@ struct fiodgname_arg {
 #define	FIOSEEKDATA	_IOWR('f', 97, off_t)	/* SEEK_DATA */
 #define	FIOSEEKHOLE	_IOWR('f', 98, off_t)	/* SEEK_HOLE */
 
+#ifdef _KERNEL
+#ifdef COMPAT_FREEBSD32
+struct fiodgname_arg32 {
+	int		len;
+	uint32_t	buf;	/* (void *) */
+};
+#define	FIODGNAME_32	_IOC_NEWTYPE(FIODGNAME, struct fiodgname_arg32)
+#endif
+
+void	*fiodgname_buf_get_ptr(void *fgnp, u_long com);
+#endif
+
 #endif /* !_SYS_FILIO_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810261759.w9QHxPqE093372>