Move 32-bit compat support for CDIOREADTOCENTRYS 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 members which require no translation.

Reviewed by:	kib (prior version), jhb
Approved by:	re (rgrimes)
Obtained from:	CheriBSD
Sponsored by:	DARPA, AFRL
Differential Review:	https://reviews.freebsd.org/D17378
This commit is contained in:
Brooks Davis 2018-10-02 23:23:56 +00:00
parent 8ac2f3ba9f
commit 4364eab875
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=339101
3 changed files with 41 additions and 40 deletions

View File

@ -63,8 +63,10 @@ __FBSDID("$FreeBSD$");
#include <sys/cdrio.h>
#include <sys/dvdio.h>
#include <sys/devicestat.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/taskqueue.h>
#include <geom/geom_disk.h>
@ -210,6 +212,17 @@ static struct cd_quirk_entry cd_quirk_table[] =
}
};
#ifdef COMPAT_FREEBSD32
struct ioc_read_toc_entry32 {
u_char address_format;
u_char starting_track;
u_short data_len;
uint32_t data; /* (struct cd_toc_entry *) */
};
#define CDIOREADTOCENTRYS_32 \
_IOC_NEWTYPE(CDIOREADTOCENTRYS, struct ioc_read_toc_entry32)
#endif
static disk_open_t cdopen;
static disk_close_t cdclose;
static disk_ioctl_t cdioctl;
@ -1272,6 +1285,29 @@ cdgetpagesize(int page_num)
return (-1);
}
static struct cd_toc_entry *
te_data_get_ptr(void *irtep, u_long cmd)
{
union {
struct ioc_read_toc_entry irte;
#ifdef COMPAT_FREEBSD32
struct ioc_read_toc_entry32 irte32;
#endif
} *irteup;
irteup = irtep;
switch (IOCPARM_LEN(cmd)) {
case sizeof(irteup->irte):
return (irteup->irte.data);
#ifdef COMPAT_FREEBSD32
case sizeof(irteup->irte32):
return ((struct cd_toc_entry *)(uintptr_t)irteup->irte32.data);
#endif
default:
panic("Unhandled ioctl command %ld", cmd);
}
}
static int
cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
{
@ -1587,6 +1623,9 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
}
break;
case CDIOREADTOCENTRYS:
#ifdef COMPAT_FREEBSD32
case CDIOREADTOCENTRYS_32:
#endif
{
struct cd_tocdata *data;
struct cd_toc_single *lead;
@ -1712,7 +1751,8 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
}
cam_periph_unlock(periph);
error = copyout(data->entries, te->data, len);
error = copyout(data->entries, te_data_get_ptr(te, cmd),
len);
free(data, M_SCSICD);
free(lead, M_SCSICD);
}

View File

@ -56,35 +56,8 @@ __FBSDID("$FreeBSD$");
#include <compat/freebsd32/freebsd32_misc.h>
#include <compat/freebsd32/freebsd32_proto.h>
CTASSERT(sizeof(struct ioc_read_toc_entry32) == 8);
CTASSERT(sizeof(struct mem_range_op32) == 12);
static int
freebsd32_ioctl_ioc_read_toc(struct thread *td,
struct freebsd32_ioctl_args *uap, struct file *fp)
{
struct ioc_read_toc_entry toce;
struct ioc_read_toc_entry32 toce32;
int error;
if ((error = copyin(uap->data, &toce32, sizeof(toce32))))
return (error);
CP(toce32, toce, address_format);
CP(toce32, toce, starting_track);
CP(toce32, toce, data_len);
PTRIN_CP(toce32, toce, data);
if ((error = fo_ioctl(fp, CDIOREADTOCENTRYS, (caddr_t)&toce,
td->td_ucred, td))) {
CP(toce, toce32, address_format);
CP(toce, toce32, starting_track);
CP(toce, toce32, data_len);
PTROUT_CP(toce, toce32, data);
error = copyout(&toce32, uap->data, sizeof(toce32));
}
return error;
}
static int
freebsd32_ioctl_fiodgname(struct thread *td,
struct freebsd32_ioctl_args *uap, struct file *fp)
@ -264,10 +237,6 @@ freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap)
}
switch (uap->com) {
case CDIOREADTOCENTRYS_32:
error = freebsd32_ioctl_ioc_read_toc(td, uap, fp);
break;
case FIODGNAME_32:
error = freebsd32_ioctl_fiodgname(td, uap, fp);
break;

View File

@ -38,13 +38,6 @@
typedef __uint32_t caddr_t32;
struct ioc_read_toc_entry32 {
u_char address_format;
u_char starting_track;
u_short data_len;
uint32_t data; /* struct cd_toc_entry* */
};
struct fiodgname_arg32 {
int len;
caddr_t32 buf;
@ -67,7 +60,6 @@ struct pci_bar_mmap32 {
int pbm_memattr;
};
#define CDIOREADTOCENTRYS_32 _IOWR('c', 5, struct ioc_read_toc_entry32)
#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)