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:
parent
8ac2f3ba9f
commit
4364eab875
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=339101
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user