summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2005-01-30 08:12:37 +0000
committersobomax <sobomax@FreeBSD.org>2005-01-30 08:12:37 +0000
commit69aa6843efc6c9eeb6337b4d4ea4111c5ccd9ea7 (patch)
tree60c80029e1db66c753066e1ca06309b6a56d0ce6 /sys/cam
parent357d55c30bf33ab6d5042b919803aac27999084a (diff)
downloadFreeBSD-src-69aa6843efc6c9eeb6337b4d4ea4111c5ccd9ea7.zip
FreeBSD-src-69aa6843efc6c9eeb6337b4d4ea4111c5ccd9ea7.tar.gz
Boot away another stackgap (one of the lest ones in linuxlator/i386) by
providing special version of CDIOCREADSUBCHANNEL ioctl(), which assumes that result has to be placed into kernel space not user space. In the long run more generic solution has to be designed WRT emulating various ioctl()s that operate on userspace buffers, but right now there is only one such ioctl() is emulated, so that it makes little sense. MFC after: 2 weeks
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_cd.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 012e3a2..11a64a7 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -1909,7 +1909,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
struct cam_periph *periph;
struct cd_softc *softc;
- int error;
+ int error, nocopyout;
periph = (struct cam_periph *)dp->d_drv1;
if (periph == NULL)
@@ -1940,6 +1940,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
}
}
+ nocopyout = 0;
switch (cmd) {
case CDIOCPLAYTRACKS:
@@ -2098,6 +2099,9 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
error = cdplay(periph, args->blk, args->len);
}
break;
+ case CDIOCREADSUBCHANNEL_SYSSPACE:
+ nocopyout = 1;
+ /* Fallthrough */
case CDIOCREADSUBCHANNEL:
{
struct ioc_read_subchannel *args
@@ -2138,8 +2142,12 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
len = min(len, ((data->header.data_len[0] << 8) +
data->header.data_len[1] +
sizeof(struct cd_sub_channel_header)));
- if (copyout(data, args->data, len) != 0) {
- error = EFAULT;
+ if (nocopyout == 0) {
+ if (copyout(data, args->data, len) != 0) {
+ error = EFAULT;
+ }
+ } else {
+ bcopy(data, args->data, len);
}
free(data, M_TEMP);
}
OpenPOWER on IntegriCloud