Dear Turner,

Before 1 year ago, Turner reported and marked that gxvalid
can cause wrong validation by overflow in the calculation
of 16bit offset, like:

        offset_16bit = base_16bit + gid_16bit * const_32bit ;

I'm quite sorry for long silence without fix the problem.
Attached is the patch to detect the overflow, please let
me know how do you think of. Masatake Yamato and me think:
if too large 16bit GID causes overflow, calculated offset
will be less than base_offset. So, ( offset_16bit < base_16bit )
can check the overflow.
Unfortunately, both of Masatake Yamato and me don't have
VC++ which you used to find problematic part of gxvalid,
yet we don't know how VC++ warns about our fix.

Regards,
mpsuzuki

P.S.
Still there are several XXX parts in gxvalid, it will be fixed
in 2007. Sorry.


--- orig/src/gxvalid/gxvbsln.c
+++ mod/src/gxvalid/gxvbsln.c
@@ -131,9 +131,10 @@
     FT_UShort            offset;
     GXV_LookupValueDesc  value;
 
-    /* XXX: check range ? */
-    offset = (FT_UShort)( base_value.u +
-                          ( relative_gindex * sizeof ( FT_UShort ) ) );
+    offset = base_value.u +
+             relative_gindex * ( FT_UShort ) sizeof ( FT_UShort );
+    if ( offset < base_value.u )
+      FT_INVALID_OFFSET;
 
     p     = valid->lookuptbl_head + offset;
     limit = lookuptbl_limit;


--- orig/src/gxvalid/gxvcommn.c
+++ mod/src/gxvalid/gxvcommn.c
@@ -1400,9 +1400,10 @@
     FT_UShort            offset;
     GXV_LookupValueDesc  value;
 
-    /* XXX: check range? */
-    offset = (FT_UShort)( base_value.u +
-                          relative_gindex * sizeof ( FT_UShort ) );
+    offset = base_value.u +
+             relative_gindex * ( FT_UShort ) sizeof ( FT_UShort );
+    if ( offset < base_value.u )
+      FT_INVALID_OFFSET;
 
     p     = valid->lookuptbl_head + offset;
     limit = lookuptbl_limit;


--- orig/src/gxvalid/gxvlcar.c
+++ mod/src/gxvalid/gxvlcar.c
@@ -157,9 +157,11 @@
 
     FT_UNUSED( lookuptbl_limit );
 
-    /* XXX: check range? */
-    offset = (FT_UShort)( base_value.u +
-                          relative_gindex * sizeof ( FT_UShort ) );
+    offset = base_value.u +
+             relative_gindex * ( FT_UShort ) sizeof ( FT_UShort );
+    if ( offset < base_value.u )
+      FT_INVALID_OFFSET;
+
     p      = valid->root->base + offset;
     limit  = valid->root->limit;
 


--- orig/src/gxvalid/gxvmort4.c
+++ mod/src/gxvalid/gxvmort4.c
@@ -87,9 +87,10 @@
     FT_UShort            offset;
     GXV_LookupValueDesc  value;
 
-    /* XXX: check range? */
-    offset = (FT_UShort)( base_value.u +
-                          relative_gindex * sizeof ( FT_UShort ) );
+    offset = base_value.u +
+             relative_gindex * ( FT_UShort ) sizeof ( FT_UShort );
+    if ( offset < base_value.u )
+      FT_INVALID_OFFSET;
 
     p     = valid->lookuptbl_head + offset;
     limit = lookuptbl_limit;


--- orig/src/gxvalid/gxvmorx1.c
+++ mod/src/gxvalid/gxvmorx1.c
@@ -179,9 +179,10 @@
     FT_UShort            offset;
     GXV_LookupValueDesc  value;
 
-    /* XXX: check range? */
-    offset = (FT_UShort)( base_value.u +
-                          relative_gindex * sizeof ( FT_UShort ) );
+    offset = base_value.u +
+             relative_gindex * ( FT_UShort ) sizeof ( FT_UShort );
+    if ( offset < base_value.u )
+      FT_INVALID_OFFSET;
 
     p     = valid->lookuptbl_head + offset;
     limit = lookuptbl_limit;


--- orig/src/gxvalid/gxvopbd.c
+++ mod/src/gxvalid/gxvopbd.c
@@ -141,9 +141,10 @@
     FT_UNUSED( lookuptbl_limit );
     FT_UNUSED( valid );
 
-    /* XXX: check range? */
-    value.u = (FT_UShort)( base_value.u +
-                           relative_gindex * 4 * sizeof ( FT_Short ) );
+    value.u = base_value.u +
+              relative_gindex * 4 * ( FT_UShort ) sizeof ( FT_Short );
+    if ( value.u < base_value.u )
+      FT_INVALID_OFFSET;
 
     return value;
   }


--- orig/src/gxvalid/gxvprop.c
+++ mod/src/gxvalid/gxvprop.c
@@ -213,9 +213,11 @@
     FT_UShort            offset;
     GXV_LookupValueDesc  value;
 
-    /* XXX: check range? */
-    offset = (FT_UShort)( base_value.u +
-                          relative_gindex * sizeof( FT_UShort ) );
+    offset = base_value.u +
+             relative_gindex * ( FT_UShort ) sizeof( FT_UShort );
+    if ( offset < base_value.u )
+      FT_INVALID_OFFSET;
+
     p      = valid->lookuptbl_head + offset;
     limit  = lookuptbl_limit;
 





_______________________________________________
Freetype-devel mailing list
Freetype-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/freetype-devel

Reply via email to