Date: Wed, 3 Jul 2019 00:10:01 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r349627 - in head/sys: cam/scsi compat/linux sys Message-ID: <201907030010.x630A19M052020@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Wed Jul 3 00:10:01 2019 New Revision: 349627 URL: https://svnweb.freebsd.org/changeset/base/349627 Log: Remove the CDIOCREADSUBCHANNEL_SYSSPACE ioctl. This was added for emulation of Linux's CDROMSUBCHNL, but allows users with read access to a cd(4) device to overwrite kernel memory provided that the driver detects some media present. Reimplement CDROMSUBCHNL by bouncing the data from CDIOCREADSUBCHANNEL through the linux_cdrom_subchnl structure passed from userspace. admbugs: 768 Reported by: Alex Fortune Security: CVE-2019-5602 Security: FreeBSD-SA-19:11.cd_ioctl Modified: head/sys/cam/scsi/scsi_cd.c head/sys/compat/linux/linux_ioctl.c head/sys/sys/cdio.h Modified: head/sys/cam/scsi/scsi_cd.c ============================================================================== --- head/sys/cam/scsi/scsi_cd.c Wed Jul 3 00:04:50 2019 (r349626) +++ head/sys/cam/scsi/scsi_cd.c Wed Jul 3 00:10:01 2019 (r349627) @@ -1314,7 +1314,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int f struct cam_periph *periph; struct cd_softc *softc; - int nocopyout, error = 0; + int error = 0; periph = (struct cam_periph *)dp->d_drv1; cam_periph_lock(periph); @@ -1356,7 +1356,6 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int f */ cam_periph_unlock(periph); - nocopyout = 0; switch (cmd) { case CDIOCPLAYTRACKS: @@ -1532,9 +1531,6 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int f cam_periph_unlock(periph); } break; - case CDIOCREADSUBCHANNEL_SYSSPACE: - nocopyout = 1; - /* Fallthrough */ case CDIOCREADSUBCHANNEL: { struct ioc_read_subchannel *args @@ -1579,13 +1575,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int f data->header.data_len[1] + sizeof(struct cd_sub_channel_header))); cam_periph_unlock(periph); - if (nocopyout == 0) { - if (copyout(data, args->data, len) != 0) { - error = EFAULT; - } - } else { - bcopy(data, args->data, len); - } + error = copyout(data, args->data, len); free(data, M_SCSICD); } break; Modified: head/sys/compat/linux/linux_ioctl.c ============================================================================== --- head/sys/compat/linux/linux_ioctl.c Wed Jul 3 00:04:50 2019 (r349626) +++ head/sys/compat/linux/linux_ioctl.c Wed Jul 3 00:10:01 2019 (r349627) @@ -1489,16 +1489,26 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioct struct ioc_read_subchannel bsdsc; struct cd_sub_channel_info bsdinfo; + error = copyin((void *)args->arg, &sc, sizeof(sc)); + if (error) + break; + + /* + * Invoke the native ioctl and bounce the returned data through + * the userspace buffer. This works because the Linux structure + * is the same size as our structures for the subchannel header + * and position data. + */ bsdsc.address_format = CD_LBA_FORMAT; bsdsc.data_format = CD_CURRENT_POSITION; bsdsc.track = 0; - bsdsc.data_len = sizeof(bsdinfo); - bsdsc.data = &bsdinfo; - error = fo_ioctl(fp, CDIOCREADSUBCHANNEL_SYSSPACE, - (caddr_t)&bsdsc, td->td_ucred, td); + bsdsc.data_len = sizeof(sc); + bsdsc.data = (void *)args->arg; + error = fo_ioctl(fp, CDIOCREADSUBCHANNEL, (caddr_t)&bsdsc, + td->td_ucred, td); if (error) break; - error = copyin((void *)args->arg, &sc, sizeof(sc)); + error = copyin((void *)args->arg, &bsdinfo, sizeof(bsdinfo)); if (error) break; sc.cdsc_audiostatus = bsdinfo.header.audio_status; Modified: head/sys/sys/cdio.h ============================================================================== --- head/sys/sys/cdio.h Wed Jul 3 00:04:50 2019 (r349626) +++ head/sys/sys/cdio.h Wed Jul 3 00:10:01 2019 (r349627) @@ -274,11 +274,4 @@ struct ioc_capability { /*<2>*/ #define CDIOCCAPABILITY _IOR('c',30,struct ioc_capability) /*<2>*/ -/* - * Special version of CDIOCREADSUBCHANNEL which assumes that - * ioc_read_subchannel->data points to the kernel memory. For - * use in compatibility layers. - */ -#define CDIOCREADSUBCHANNEL_SYSSPACE _IOWR('c', 31, struct ioc_read_subchannel) - #endif /* !_SYS_CDIO_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201907030010.x630A19M052020>