summaryrefslogtreecommitdiffstats
path: root/sys/dev/mcd
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/dev/mcd
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/dev/mcd')
-rw-r--r--sys/dev/mcd/mcd.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/dev/mcd/mcd.c b/sys/dev/mcd/mcd.c
index db35190..e9cc575 100644
--- a/sys/dev/mcd/mcd.c
+++ b/sys/dev/mcd/mcd.c
@@ -135,7 +135,8 @@ static void mcd_soft_reset(struct mcd_softc *);
static int mcd_hard_reset(struct mcd_softc *);
static int mcd_setmode(struct mcd_softc *, int mode);
static int mcd_getqchan(struct mcd_softc *, struct mcd_qchninfo *q);
-static int mcd_subchan(struct mcd_softc *, struct ioc_read_subchannel *sc);
+static int mcd_subchan(struct mcd_softc *, struct ioc_read_subchannel *sc,
+ int nocopyout);
static int mcd_toc_header(struct mcd_softc *, struct ioc_toc_header *th);
static int mcd_read_toc(struct mcd_softc *);
static int mcd_toc_entrys(struct mcd_softc *, struct ioc_read_toc_entry *te);
@@ -440,8 +441,10 @@ MCD_TRACE("ioctl called 0x%lx\n", cmd);
return mcd_playblocks(sc, (struct ioc_play_blocks *) addr);
case CDIOCPLAYMSF:
return mcd_playmsf(sc, (struct ioc_play_msf *) addr);
+ case CDIOCREADSUBCHANNEL_SYSSPACE:
+ return mcd_subchan(sc, (struct ioc_read_subchannel *) addr, 1);
case CDIOCREADSUBCHANNEL:
- return mcd_subchan(sc, (struct ioc_read_subchannel *) addr);
+ return mcd_subchan(sc, (struct ioc_read_subchannel *) addr, 0);
case CDIOREADTOCHEADER:
return mcd_toc_header(sc, (struct ioc_toc_header *) addr);
case CDIOREADTOCENTRYS:
@@ -1357,7 +1360,7 @@ mcd_getqchan(struct mcd_softc *sc, struct mcd_qchninfo *q)
}
static int
-mcd_subchan(struct mcd_softc *sc, struct ioc_read_subchannel *sch)
+mcd_subchan(struct mcd_softc *sc, struct ioc_read_subchannel *sch, int nocopyout)
{
struct mcd_qchninfo q;
struct cd_sub_channel_info data;
@@ -1423,7 +1426,10 @@ mcd_subchan(struct mcd_softc *sc, struct ioc_read_subchannel *sch)
break;
}
- return copyout(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len));
+ if (nocopyout == 0)
+ return copyout(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len));
+ bcopy(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len));
+ return (0)
}
static int
OpenPOWER on IntegriCloud