summaryrefslogtreecommitdiffstats
path: root/sys/scsi
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1996-01-30 12:59:00 +0000
committerache <ache@FreeBSD.org>1996-01-30 12:59:00 +0000
commit37f4a0aab182a435be766452eb2f53205cbded7d (patch)
tree8b7fb6d533b2156f0260d1363047359682c6b47f /sys/scsi
parent7b11911f521e96aa70e311bee69358da327490cb (diff)
downloadFreeBSD-src-37f4a0aab182a435be766452eb2f53205cbded7d.zip
FreeBSD-src-37f4a0aab182a435be766452eb2f53205cbded7d.tar.gz
READTOCENTRYS: handle 0 and lead out requests, add argument checking
Diffstat (limited to 'sys/scsi')
-rw-r--r--sys/scsi/cd.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c
index 0caead8..e7650d6 100644
--- a/sys/scsi/cd.c
+++ b/sys/scsi/cd.c
@@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
- * $Id: cd.c,v 1.55 1995/12/30 13:56:28 joerg Exp $
+ * $Id: cd.c,v 1.56 1996/01/05 20:12:39 wollman Exp $
*/
#include "opt_bounce.h"
@@ -741,7 +741,7 @@ cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
}
break;
case CDIOREADTOCHEADER:
- { /* ??? useless bcopy? XXX */
+ {
struct ioc_toc_header th;
error = cd_read_toc(unit, 0, 0,
(struct cd_toc_entry *)&th, sizeof th);
@@ -755,28 +755,51 @@ cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
{
struct cd_toc {
struct ioc_toc_header header;
- struct cd_toc_entry entries[65];
+ struct cd_toc_entry entries[100];
} data;
struct ioc_read_toc_entry *te =
(struct ioc_read_toc_entry *) addr;
struct ioc_toc_header *th;
- u_int32 len = te->data_len;
+ u_int32 len;
+ u_int32 starting_track = te->starting_track;
+
+ if ( te->data_len < sizeof(struct cd_toc_entry)
+ || (te->data_len % sizeof(struct cd_toc_entry)) != 0
+ || te->address_format != CD_MSF_FORMAT
+ && te->address_format != CD_LBA_FORMAT
+ ) {
+ error = EINVAL;
+ break;
+ }
th = &data.header;
-
- if (len > sizeof(data.entries) || len < sizeof(struct cd_toc_entry)) {
+ error = cd_read_toc(unit, 0, 0,
+ (struct cd_toc_entry *)th, sizeof *th);
+ if (error)
+ break;
+ if (starting_track == 0)
+ starting_track = th->starting_track;
+ else if (starting_track == 170)
+ starting_track = th->ending_track + 1;
+ else if (starting_track < th->starting_track ||
+ starting_track > th->ending_track + 1) {
+ error = EINVAL;
+ break;
+ }
+ len = ((th->ending_track + 1 - starting_track) + 1) *
+ sizeof(struct cd_toc_entry);
+ if (te->data_len < len)
+ len = te->data_len;
+ if (len > sizeof(data.entries)) {
error = EINVAL;
break;
}
error = cd_read_toc(unit, te->address_format,
- te->starting_track,
+ starting_track,
(struct cd_toc_entry *)&data,
len + sizeof(struct ioc_toc_header));
if (error)
break;
- len = min(len, ((((th->len & 0xff) << 8) + ((th->len >> 8))) - (sizeof(th->starting_track) + sizeof(th->ending_track))));
- if (copyout(data.entries, te->data, len) != 0) {
- error = EFAULT;
- }
+ error = copyout(data.entries, te->data, len);
}
break;
case CDIOCSETPATCH:
OpenPOWER on IntegriCloud