summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1996-01-30 13:15:28 +0000
committerache <ache@FreeBSD.org>1996-01-30 13:15:28 +0000
commit9e0a71c3eebd8d8e34dfa434ee6b139736c61490 (patch)
tree2dda7a4548814e28aa9e4390c9e55f3d31d46f0c
parent37f4a0aab182a435be766452eb2f53205cbded7d (diff)
downloadFreeBSD-src-9e0a71c3eebd8d8e34dfa434ee6b139736c61490.zip
FreeBSD-src-9e0a71c3eebd8d8e34dfa434ee6b139736c61490.tar.gz
READTOCENTRYS: protect against stack overflow when incorrect data
stored in CD's TOC
-rw-r--r--sys/dev/mcd/mcd.c20
-rw-r--r--sys/i386/isa/mcd.c20
-rw-r--r--sys/i386/isa/wcd.c7
3 files changed, 30 insertions, 17 deletions
diff --git a/sys/dev/mcd/mcd.c b/sys/dev/mcd/mcd.c
index b77b2ec..30821ef 100644
--- a/sys/dev/mcd/mcd.c
+++ b/sys/dev/mcd/mcd.c
@@ -40,7 +40,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: mcd.c,v 1.60 1996/01/30 10:31:06 ache Exp $
+ * $Id: mcd.c,v 1.61 1996/01/30 12:07:06 ache Exp $
*/
static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";
@@ -1431,15 +1431,14 @@ mcd_toc_entrys(int unit, struct ioc_read_toc_entry *te)
struct mcd_data *cd = mcd_data + unit;
struct cd_toc_entry entries[MCD_MAXTOCS];
struct ioc_toc_header th;
- int rc, n, trk, len = te->data_len;
+ int rc, n, trk, len;
- if ( len < sizeof(entries[0])
- || (len % sizeof(entries[0])) != 0
+ if ( te->data_len < sizeof(entries[0])
+ || (te->data_len % sizeof(entries[0])) != 0
+ || te->address_format != CD_MSF_FORMAT
+ && te->address_format != CD_LBA_FORMAT
)
return EINVAL;
- if (te->address_format != CD_MSF_FORMAT &&
- te->address_format != CD_LBA_FORMAT)
- return EINVAL;
/* Copy the toc header */
if ((rc = mcd_toc_header(unit, &th)) != 0)
@@ -1454,6 +1453,13 @@ mcd_toc_entrys(int unit, struct ioc_read_toc_entry *te)
else if (trk < th.starting_track || trk > th.ending_track + 1)
return EINVAL;
+ len = ((th.ending_track + 1 - trk) + 1) *
+ sizeof(entries[0]);
+ if (te->data_len < len)
+ len = te->data_len;
+ if (len > sizeof(entries))
+ return EINVAL;
+
/* Make sure we have a valid toc */
if ((rc=mcd_read_toc(unit)) != 0)
return rc;
diff --git a/sys/i386/isa/mcd.c b/sys/i386/isa/mcd.c
index b77b2ec..30821ef 100644
--- a/sys/i386/isa/mcd.c
+++ b/sys/i386/isa/mcd.c
@@ -40,7 +40,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: mcd.c,v 1.60 1996/01/30 10:31:06 ache Exp $
+ * $Id: mcd.c,v 1.61 1996/01/30 12:07:06 ache Exp $
*/
static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";
@@ -1431,15 +1431,14 @@ mcd_toc_entrys(int unit, struct ioc_read_toc_entry *te)
struct mcd_data *cd = mcd_data + unit;
struct cd_toc_entry entries[MCD_MAXTOCS];
struct ioc_toc_header th;
- int rc, n, trk, len = te->data_len;
+ int rc, n, trk, len;
- if ( len < sizeof(entries[0])
- || (len % sizeof(entries[0])) != 0
+ if ( te->data_len < sizeof(entries[0])
+ || (te->data_len % sizeof(entries[0])) != 0
+ || te->address_format != CD_MSF_FORMAT
+ && te->address_format != CD_LBA_FORMAT
)
return EINVAL;
- if (te->address_format != CD_MSF_FORMAT &&
- te->address_format != CD_LBA_FORMAT)
- return EINVAL;
/* Copy the toc header */
if ((rc = mcd_toc_header(unit, &th)) != 0)
@@ -1454,6 +1453,13 @@ mcd_toc_entrys(int unit, struct ioc_read_toc_entry *te)
else if (trk < th.starting_track || trk > th.ending_track + 1)
return EINVAL;
+ len = ((th.ending_track + 1 - trk) + 1) *
+ sizeof(entries[0]);
+ if (te->data_len < len)
+ len = te->data_len;
+ if (len > sizeof(entries))
+ return EINVAL;
+
/* Make sure we have a valid toc */
if ((rc=mcd_read_toc(unit)) != 0)
return rc;
diff --git a/sys/i386/isa/wcd.c b/sys/i386/isa/wcd.c
index 3821b1c..94c76a5 100644
--- a/sys/i386/isa/wcd.c
+++ b/sys/i386/isa/wcd.c
@@ -767,11 +767,10 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
if ( te->data_len < sizeof(toc->tab[0])
|| (te->data_len % sizeof(toc->tab[0])) != 0
+ || te->address_format != CD_MSF_FORMAT
+ && te->address_format != CD_LBA_FORMAT
)
return EINVAL;
- if (te->address_format != CD_MSF_FORMAT &&
- te->address_format != CD_LBA_FORMAT)
- return EINVAL;
if (starting_track == 0)
starting_track = toc->hdr.starting_track;
@@ -785,6 +784,8 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
sizeof(toc->tab[0]);
if (te->data_len < len)
len = te->data_len;
+ if (len > sizeof(toc->tab))
+ return EINVAL;
/* Convert to MSF format, if needed. */
if (te->address_format == CD_MSF_FORMAT) {
OpenPOWER on IntegriCloud