aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/md
diff options
context:
space:
mode:
authorBrooks Davis <brooks@FreeBSD.org>2018-03-27 16:07:54 +0000
committerBrooks Davis <brooks@FreeBSD.org>2018-03-27 16:07:54 +0000
commit026cac821351142e0130eea17b1ba0e082ecbc69 (patch)
tree190290030ec6c1f4f5cc8ba1e627d6c76dcdb5a3 /sys/dev/md
parentf137973487f6170f8cb3285ec58aed46e9e3e6f9 (diff)
Notes
Diffstat (limited to 'sys/dev/md')
-rw-r--r--sys/dev/md/md.c130
1 files changed, 107 insertions, 23 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index d976ced2391b..d5908e771613 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -60,6 +60,7 @@
* From: src/sys/dev/vn/vn.c,v 1.122 2000/12/16 16:06:03
*/
+#include "opt_compat.h"
#include "opt_rootdevname.h"
#include "opt_geom.h"
#include "opt_md.h"
@@ -130,6 +131,30 @@ struct md_req {
size_t md_units_nitems; /* items in md_units array */
};
+#ifdef COMPAT_FREEBSD32
+struct md_ioctl32 {
+ unsigned md_version;
+ unsigned md_unit;
+ enum md_types md_type;
+ uint32_t md_file;
+ off_t md_mediasize;
+ unsigned md_sectorsize;
+ unsigned md_options;
+ uint64_t md_base;
+ int md_fwheads;
+ int md_fwsectors;
+ uint32_t md_label;
+ int md_pad[MDNPAD];
+} __attribute__((__packed__));
+CTASSERT((sizeof(struct md_ioctl32)) == 436);
+
+#define MDIOCATTACH_32 _IOC_NEWTYPE(MDIOCATTACH, struct md_ioctl32)
+#define MDIOCDETACH_32 _IOC_NEWTYPE(MDIOCDETACH, struct md_ioctl32)
+#define MDIOCQUERY_32 _IOC_NEWTYPE(MDIOCQUERY, struct md_ioctl32)
+#define MDIOCLIST_32 _IOC_NEWTYPE(MDIOCLIST, struct md_ioctl32)
+#define MDIOCRESIZE_32 _IOC_NEWTYPE(MDIOCRESIZE, struct md_ioctl32)
+#endif /* COMPAT_FREEBSD32 */
+
static MALLOC_DEFINE(M_MD, "md_disk", "Memory Disk");
static MALLOC_DEFINE(M_MDSECT, "md_sectors", "Memory Disk Sectors");
@@ -1396,8 +1421,10 @@ mdcreate_vnode(struct md_s *sc, struct md_req *mdr, struct thread *td)
error = copyinstr(fname, sc->file, sizeof(sc->file), NULL);
if (error != 0)
return (error);
- } else
+ } else if (mdr->md_file_seg == UIO_SYSSPACE)
strlcpy(sc->file, fname, sizeof(sc->file));
+ else
+ return (EDOOFUS);
/*
* If the user specified that this is a read only device, don't
@@ -1859,61 +1886,111 @@ kern_mdlist(struct md_req *mdr)
return (error);
}
+/* Copy members that are not userspace pointers. */
+#define MD_IOCTL2REQ(mdio, mdr) do { \
+ (mdr)->md_unit = (mdio)->md_unit; \
+ (mdr)->md_type = (mdio)->md_type; \
+ (mdr)->md_mediasize = (mdio)->md_mediasize; \
+ (mdr)->md_sectorsize = (mdio)->md_sectorsize; \
+ (mdr)->md_options = (mdio)->md_options; \
+ (mdr)->md_fwheads = (mdio)->md_fwheads; \
+ (mdr)->md_fwsectors = (mdio)->md_fwsectors; \
+ (mdr)->md_units = &(mdio)->md_pad[0]; \
+ (mdr)->md_units_nitems = nitems((mdio)->md_pad); \
+} while(0)
+
+/* Copy members that might have been updated */
+#define MD_REQ2IOCTL(mdr, mdio) do { \
+ (mdio)->md_unit = (mdr)->md_unit; \
+ (mdio)->md_type = (mdr)->md_type; \
+ (mdio)->md_mediasize = (mdr)->md_mediasize; \
+ (mdio)->md_sectorsize = (mdr)->md_sectorsize; \
+ (mdio)->md_options = (mdr)->md_options; \
+ (mdio)->md_fwheads = (mdr)->md_fwheads; \
+ (mdio)->md_fwsectors = (mdr)->md_fwsectors; \
+} while(0)
+
static int
mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
struct thread *td)
{
struct md_req mdr;
- struct md_ioctl *mdio;
int error;
if (md_debug)
printf("mdctlioctl(%s %lx %p %x %p)\n",
devtoname(dev), cmd, addr, flags, td);
+ bzero(&mdr, sizeof(mdr));
switch (cmd) {
case MDIOCATTACH:
case MDIOCDETACH:
case MDIOCRESIZE:
case MDIOCQUERY:
- case MDIOCLIST:
- mdio = (struct md_ioctl *)addr;
+ case MDIOCLIST: {
+ struct md_ioctl *mdio = (struct md_ioctl *)addr;
if (mdio->md_version != MDIOVERSION)
return (EINVAL);
- mdr.md_unit = mdio->md_unit;
- mdr.md_type = mdio->md_type;
- mdr.md_mediasize = mdio->md_mediasize;
- mdr.md_sectorsize = mdio->md_sectorsize;
- mdr.md_options = mdio->md_options;
- mdr.md_fwheads = mdio->md_fwheads;
- mdr.md_fwsectors = mdio->md_fwsectors;
+ MD_IOCTL2REQ(mdio, &mdr);
mdr.md_file = mdio->md_file;
+ mdr.md_file_seg = UIO_USERSPACE;
/* If the file is adjacent to the md_ioctl it's in kernel. */
if ((void *)mdio->md_file == (void *)(mdio + 1))
mdr.md_file_seg = UIO_SYSSPACE;
- else
- mdr.md_file_seg = UIO_USERSPACE;
mdr.md_label = mdio->md_label;
- mdr.md_units = &mdio->md_pad[0];
- mdr.md_units_nitems = nitems(mdio->md_pad);
+ break;
+ }
+#ifdef COMPAT_FREEBSD32
+ case MDIOCATTACH_32:
+ case MDIOCDETACH_32:
+ case MDIOCRESIZE_32:
+ case MDIOCQUERY_32:
+ case MDIOCLIST_32: {
+ struct md_ioctl32 *mdio = (struct md_ioctl32 *)addr;
+ if (mdio->md_version != MDIOVERSION)
+ return (EINVAL);
+ MD_IOCTL2REQ(mdio, &mdr);
+ mdr.md_file = (void *)(uintptr_t)mdio->md_file;
+ mdr.md_file_seg = UIO_USERSPACE;
+ mdr.md_label = (void *)(uintptr_t)mdio->md_label;
+ break;
+ }
+#endif
+ default:
+ /* Fall through to handler switch. */
break;
}
error = 0;
switch (cmd) {
case MDIOCATTACH:
+#ifdef COMPAT_FREEBSD32
+ case MDIOCATTACH_32:
+#endif
error = kern_mdattach(td, &mdr);
break;
case MDIOCDETACH:
+#ifdef COMPAT_FREEBSD32
+ case MDIOCDETACH_32:
+#endif
error = kern_mddetach(td, &mdr);
break;
case MDIOCRESIZE:
+#ifdef COMPAT_FREEBSD32
+ case MDIOCRESIZE_32:
+#endif
error = kern_mdresize(&mdr);
break;
case MDIOCQUERY:
+#ifdef COMPAT_FREEBSD32
+ case MDIOCQUERY_32:
+#endif
error = kern_mdquery(&mdr);
break;
case MDIOCLIST:
+#ifdef COMPAT_FREEBSD32
+ case MDIOCLIST_32:
+#endif
error = kern_mdlist(&mdr);
break;
default:
@@ -1922,14 +1999,21 @@ mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
switch (cmd) {
case MDIOCATTACH:
- case MDIOCQUERY:
- mdio->md_unit = mdr.md_unit;
- mdio->md_type = mdr.md_type;
- mdio->md_mediasize = mdr.md_mediasize;
- mdio->md_sectorsize = mdr.md_sectorsize;
- mdio->md_options = mdr.md_options;
- mdio->md_fwheads = mdr.md_fwheads;
- mdio->md_fwsectors = mdr.md_fwsectors;
+ case MDIOCQUERY: {
+ struct md_ioctl *mdio = (struct md_ioctl *)addr;
+ MD_REQ2IOCTL(&mdr, mdio);
+ break;
+ }
+#ifdef COMPAT_FREEBSD32
+ case MDIOCATTACH_32:
+ case MDIOCQUERY_32: {
+ struct md_ioctl32 *mdio = (struct md_ioctl32 *)addr;
+ MD_REQ2IOCTL(&mdr, mdio);
+ break;
+ }
+#endif
+ default:
+ /* Other commands to not alter mdr. */
break;
}