Index: head/sys/compat/freebsd32/freebsd32_ioctl.h =================================================================== --- head/sys/compat/freebsd32/freebsd32_ioctl.h +++ head/sys/compat/freebsd32/freebsd32_ioctl.h @@ -45,22 +45,6 @@ uint32_t data; /* struct cd_toc_entry* */ }; -#define MDNPAD32 MDNPAD -struct md_ioctl32 { - unsigned md_version; /* Structure layout version */ - unsigned md_unit; /* unit number */ - enum md_types md_type; /* type of disk */ - caddr_t32 md_file; /* pathname of file to mount */ - off_t md_mediasize; /* size of disk in bytes */ - unsigned md_sectorsize; /* sectorsize */ - unsigned md_options; /* options */ - u_int64_t md_base; /* base address */ - int md_fwheads; /* firmware heads */ - int md_fwsectors; /* firmware sectors */ - caddr_t32 md_label; /* label of the device */ - int md_pad[MDNPAD32]; /* padding for future ideas */ -} __attribute__((__packed__)); - struct fiodgname_arg32 { int len; caddr_t32 buf; @@ -112,10 +96,6 @@ }; #define CDIOREADTOCENTRYS_32 _IOWR('c', 5, struct ioc_read_toc_entry32) -#define MDIOCATTACH_32 _IOC(IOC_INOUT, 'm', 0, sizeof(struct md_ioctl32)) -#define MDIOCDETACH_32 _IOC(IOC_INOUT, 'm', 1, sizeof(struct md_ioctl32)) -#define MDIOCQUERY_32 _IOC(IOC_INOUT, 'm', 2, sizeof(struct md_ioctl32)) -#define MDIOCLIST_32 _IOC(IOC_INOUT, 'm', 3, sizeof(struct md_ioctl32)) #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) Index: head/sys/compat/freebsd32/freebsd32_ioctl.c =================================================================== --- head/sys/compat/freebsd32/freebsd32_ioctl.c +++ head/sys/compat/freebsd32/freebsd32_ioctl.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -58,90 +57,13 @@ #include #include -CTASSERT((sizeof(struct md_ioctl32)) == 436); CTASSERT(sizeof(struct ioc_read_toc_entry32) == 8); CTASSERT(sizeof(struct mem_range_op32) == 12); CTASSERT(sizeof(struct pci_conf_io32) == 36); CTASSERT(sizeof(struct pci_match_conf32) == 44); CTASSERT(sizeof(struct pci_conf32) == 44); - static int -freebsd32_ioctl_md(struct thread *td, struct freebsd32_ioctl_args *uap, - struct file *fp) -{ - struct md_ioctl mdv; - struct md_ioctl32 md32; - u_long com = 0; - int i, error; - - if (uap->com & IOC_IN) { - if ((error = copyin(uap->data, &md32, sizeof(md32)))) { - return (error); - } - CP(md32, mdv, md_version); - CP(md32, mdv, md_unit); - CP(md32, mdv, md_type); - PTRIN_CP(md32, mdv, md_file); - CP(md32, mdv, md_mediasize); - CP(md32, mdv, md_sectorsize); - CP(md32, mdv, md_options); - CP(md32, mdv, md_base); - CP(md32, mdv, md_fwheads); - CP(md32, mdv, md_fwsectors); - PTRIN_CP(md32, mdv, md_label); - } else if (uap->com & IOC_OUT) { - /* - * Zero the buffer so the user always - * gets back something deterministic. - */ - bzero(&mdv, sizeof mdv); - } - - switch (uap->com) { - case MDIOCATTACH_32: - com = MDIOCATTACH; - break; - case MDIOCDETACH_32: - com = MDIOCDETACH; - break; - case MDIOCQUERY_32: - com = MDIOCQUERY; - break; - case MDIOCLIST_32: - com = MDIOCLIST; - break; - default: - panic("%s: unknown MDIOC %#x", __func__, uap->com); - } - error = fo_ioctl(fp, com, (caddr_t)&mdv, td->td_ucred, td); - if (error == 0 && (com & IOC_OUT)) { - CP(mdv, md32, md_version); - CP(mdv, md32, md_unit); - CP(mdv, md32, md_type); - PTROUT_CP(mdv, md32, md_file); - CP(mdv, md32, md_mediasize); - CP(mdv, md32, md_sectorsize); - CP(mdv, md32, md_options); - CP(mdv, md32, md_base); - CP(mdv, md32, md_fwheads); - CP(mdv, md32, md_fwsectors); - PTROUT_CP(mdv, md32, md_label); - if (com == MDIOCLIST) { - /* - * Use MDNPAD, and not MDNPAD32. Padding is - * allocated and used by compat32 ABI. - */ - for (i = 0; i < MDNPAD; i++) - CP(mdv, md32, md_pad[i]); - } - error = copyout(&md32, uap->data, sizeof(md32)); - } - return error; -} - - -static int freebsd32_ioctl_ioc_read_toc(struct thread *td, struct freebsd32_ioctl_args *uap, struct file *fp) { @@ -414,13 +336,6 @@ } switch (uap->com) { - case MDIOCATTACH_32: /* FALLTHROUGH */ - case MDIOCDETACH_32: /* FALLTHROUGH */ - case MDIOCQUERY_32: /* FALLTHROUGH */ - case MDIOCLIST_32: - error = freebsd32_ioctl_md(td, uap, fp); - break; - case CDIOREADTOCENTRYS_32: error = freebsd32_ioctl_ioc_read_toc(td, uap, fp); break; Index: head/sys/dev/md/md.c =================================================================== --- head/sys/dev/md/md.c +++ head/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 @@ 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 @@ 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 @@ 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 @@ 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; }