>> diff --git a/src/ifo_read.c b/src/ifo_read.c
>> index 4a422c6..fc5b39b 100644
>> --- a/src/ifo_read.c
>> +++ b/src/ifo_read.c
>> @@ -1177,8 +1177,7 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
>>
>>    info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE;
>>
>> -  data = (uint32_t *)malloc(info_length);
>> -  if(!data) {
>> +  if(!(data = malloc(info_length))) {
>
> Personally I prefer not to merge the lines, I think it makes the code
> harder to read, but that's not important..

Fine w/ me. I fixed the other malloc to not have the cast as well.

> Probably not this way though.
> If you initialize data and vts_ptt_srpt to NULL
> you only need
>> err_out:
>>   free(data);
>>   ifofile->vts_ptt_srpt = 0;
>>   free(vts_ptt_srpt);
>>   return 0;

New patch does it the way you suggest.
> The ifoRead_VTS is only makes the name unwieldy, gotos can't go across
> functions.

The label was long because I kept forgetting which function I was in.
This version removes it.

>> +  if(vts_ptt_srpt->nr_of_srpts * sizeof(uint32_t) > info_length) {
>
> The suggestion was to use vts_ptt_srpt->nr_of_srpts * sizeof(*data)
> so that the check matches the reads the code does no matter what type
> data has.
> And while not an issue here for several reasons I'd recommend going with
> vts_ptt_srpt->nr_of_srpts > info_length / sizeof(*data)
> which is safe from integer overflows.
> Considering how often getting this wrong leads to exploitable bugs IMO
> it's a good idea to always use the paranoid version in the hopes that
> everyone gets used to doing it in the safe way.

Let's take the high road!

Thanks for the review.

E

-- 
Erik Hovland
[email protected]
http://hovland.org/
From d5aa6a762c856ec07e264491479e35531763279e Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Sun, 10 Jul 2011 11:12:27 -0700
Subject: [PATCH 1/4] Clean up malloc calls

Both malloc calls have a cast to the type of the pointer's
type. This is not necessary in C and is poor style.
---
 src/ifo_read.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/ifo_read.c b/src/ifo_read.c
index 4a422c6..8e3b1b7 100644
--- a/src/ifo_read.c
+++ b/src/ifo_read.c
@@ -1141,7 +1141,7 @@ void ifoFree_TT_SRPT(ifo_handle_t *ifofile) {
 int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
   vts_ptt_srpt_t *vts_ptt_srpt;
   int info_length, i, j;
-  uint32_t *data;
+  uint32_t *data = NULL;
 
   if(!ifofile)
     return 0;
@@ -1156,7 +1156,7 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
                    ifofile->vtsi_mat->vts_ptt_srpt * DVD_BLOCK_LEN))
     return 0;
 
-  vts_ptt_srpt = (vts_ptt_srpt_t *)malloc(sizeof(vts_ptt_srpt_t));
+  vts_ptt_srpt = malloc(sizeof(vts_ptt_srpt_t));
   if(!vts_ptt_srpt)
     return 0;
 
@@ -1176,8 +1176,7 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
   CHECK_VALUE(vts_ptt_srpt->nr_of_srpts < 100); /* ?? */
 
   info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE;
-
-  data = (uint32_t *)malloc(info_length);
+  data = malloc(info_length);
   if(!data) {
     free(vts_ptt_srpt);
     ifofile->vts_ptt_srpt = 0;
-- 
1.7.4.1

From 59b0398576d6de77c3ea69af10d59499f168829c Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Sun, 10 Jul 2011 14:55:48 -0700
Subject: [PATCH 2/4] Clean up error paths.

Clean up the error paths of the function using goto.
---
 src/ifo_read.c |   31 +++++++++++++------------------
 1 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/src/ifo_read.c b/src/ifo_read.c
index 8e3b1b7..68cf171 100644
--- a/src/ifo_read.c
+++ b/src/ifo_read.c
@@ -1139,7 +1139,7 @@ void ifoFree_TT_SRPT(ifo_handle_t *ifofile) {
 
 
 int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
-  vts_ptt_srpt_t *vts_ptt_srpt;
+  vts_ptt_srpt_t *vts_ptt_srpt = NULL;
   int info_length, i, j;
   uint32_t *data = NULL;
 
@@ -1164,8 +1164,7 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
 
   if(!(DVDReadBytes(ifofile->file, vts_ptt_srpt, VTS_PTT_SRPT_SIZE))) {
     fprintf(stderr, "libdvdread: Unable to read PTT search table.\n");
-    free(vts_ptt_srpt);
-    return 0;
+    goto fail;
   }
 
   B2N_16(vts_ptt_srpt->nr_of_srpts);
@@ -1178,16 +1177,11 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
   info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE;
   data = malloc(info_length);
   if(!data) {
-    free(vts_ptt_srpt);
-    ifofile->vts_ptt_srpt = 0;
-    return 0;
+    goto fail;
   }
   if(!(DVDReadBytes(ifofile->file, data, info_length))) {
     fprintf(stderr, "libdvdread: Unable to read PTT search table.\n");
-    free(vts_ptt_srpt);
-    free(data);
-    ifofile->vts_ptt_srpt = 0;
-    return 0;
+    goto fail;
   }
 
   for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
@@ -1203,10 +1197,7 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
 
   vts_ptt_srpt->title = malloc(vts_ptt_srpt->nr_of_srpts * sizeof(ttu_t));
   if(!vts_ptt_srpt->title) {
-    free(vts_ptt_srpt);
-    free(data);
-    ifofile->vts_ptt_srpt = 0;
-    return 0;
+    goto fail;
   }
   for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
     int n;
@@ -1225,10 +1216,8 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
     if(!vts_ptt_srpt->title[i].ptt) {
       for(n = 0; n < i; n++)
         free(vts_ptt_srpt->title[n].ptt);
-      free(vts_ptt_srpt);
-      free(data);
-      ifofile->vts_ptt_srpt = 0;
-      return 0;
+
+      goto fail;
     }
     for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
       /* The assert placed here because of Magic Knight Rayearth Daybreak */
@@ -1258,6 +1247,12 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
   }
 
   return 1;
+
+fail:
+  free(data);
+  ifofile->vts_ptt_srpt = 0;
+  free(vts_ptt_srpt);
+  return 0;
 }
 
 
-- 
1.7.4.1

From 3549b05cd5b8b39f512d38ec3edcc34dfb0974d0 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Sun, 10 Jul 2011 14:59:38 -0700
Subject: [PATCH 3/4] Conditional style change

---
 src/ifo_read.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/ifo_read.c b/src/ifo_read.c
index 68cf171..5f7ffa9 100644
--- a/src/ifo_read.c
+++ b/src/ifo_read.c
@@ -1176,9 +1176,9 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
 
   info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE;
   data = malloc(info_length);
-  if(!data) {
+  if(!data)
     goto fail;
-  }
+
   if(!(DVDReadBytes(ifofile->file, data, info_length))) {
     fprintf(stderr, "libdvdread: Unable to read PTT search table.\n");
     goto fail;
@@ -1196,19 +1196,21 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
   vts_ptt_srpt->ttu_offset = data;
 
   vts_ptt_srpt->title = malloc(vts_ptt_srpt->nr_of_srpts * sizeof(ttu_t));
-  if(!vts_ptt_srpt->title) {
+  if(!vts_ptt_srpt->title)
     goto fail;
-  }
+
   for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
     int n;
     if(i < vts_ptt_srpt->nr_of_srpts - 1)
       n = (data[i+1] - data[i]);
     else
       n = (vts_ptt_srpt->last_byte + 1 - data[i]);
+
     /* assert(n > 0 && (n % 4) == 0);
        Magic Knight Rayearth Daybreak is mastered very strange and has
        Titles with 0 PTTs. */
     if(n < 0) n = 0;
+
     CHECK_VALUE(n % 4 == 0);
 
     vts_ptt_srpt->title[i].nr_of_ptts = n / 4;
-- 
1.7.4.1

From cf815ce6a4daae2d5b04c1fa16af362938bc1f60 Mon Sep 17 00:00:00 2001
From: Erik Hovland <[email protected]>
Date: Sun, 10 Jul 2011 15:03:59 -0700
Subject: [PATCH 4/4] Fix crash when PTT is too short

The PTT that is allocated and read is smaller than what gets referenced.
The data is byte-swapped in place which results in writes to memory
locations outside the allocated region. Region 1 True Grit is an
example of this.

Derived from a patch submitted by John Stebbins. Thanks!
---
 src/ifo_read.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/src/ifo_read.c b/src/ifo_read.c
index 5f7ffa9..15bade5 100644
--- a/src/ifo_read.c
+++ b/src/ifo_read.c
@@ -1184,6 +1184,10 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) {
     goto fail;
   }
 
+  if(vts_ptt_srpt->nr_of_srpts > info_length / sizeof(*data)) {
+    fprintf(stderr, "libdvdread: PTT search table too small.\n");
+    goto fail;
+  }
   for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
     B2N_32(data[i]);
     /* assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1);
-- 
1.7.4.1

_______________________________________________
DVDnav-discuss mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/dvdnav-discuss

Reply via email to