freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft-devel] [PATCH RFC] src/sfnt/ttsbit0.c: fix broken pointer overflow c


From: Xi Wang
Subject: [ft-devel] [PATCH RFC] src/sfnt/ttsbit0.c: fix broken pointer overflow checks
Date: Thu, 24 Jan 2013 15:58:14 -0500

Many compilers such as gcc and clang optimize away pointer overflow
checks `p + n < p', because pointer overflow is undefined behavior.
Use a safe form `n > p_limit - p' instead.

Also avoid possible integer overflow issues, for example, using
`num_glyphs > ( p_limit - p ) / 2' rather than `num_glyphs * 2'
given a large `num_glyphs'.
---
To verify this, try the following simplified code.

void bar(void);
void foo(char *p, unsigned n)
{
    if (p + n < p)
        bar();
}

$ gcc -S -o - -O2 t.c
foo:
.LFB0:
        .cfi_startproc
        rep
        ret
        .cfi_endproc

The entire check is gone (gcc 4.7); clang produces a similar result.
---
 src/sfnt/ttsbit0.c |   20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c
index ffef10a..246b776 100644
--- a/src/sfnt/ttsbit0.c
+++ b/src/sfnt/ttsbit0.c
@@ -823,11 +823,11 @@
     image_offset = FT_NEXT_ULONG( p );
 
     /* overflow check */
-    if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
-           decoder->eblc_base )
+    p = decoder->eblc_base + decoder->strike_index_array;
+    if ( image_offset > p_limit - p )
       goto Failure;
 
-    p = decoder->eblc_base + decoder->strike_index_array + image_offset;
+    p += image_offset;
     if ( p + 8 > p_limit )
       goto NoBitmap;
 
@@ -894,11 +894,8 @@
 
         num_glyphs = FT_NEXT_ULONG( p );
 
-        /* overflow check */
-        if ( p + ( num_glyphs + 1 ) * 4 < p )
-          goto Failure;
-
-        if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
+        /* overflow check for p + ( num_glyphs + 1 ) * 4 */
+        if ( num_glyphs > ( p_limit - p ) / 4 - 1 )
           goto NoBitmap;
 
         for ( mm = 0; mm < num_glyphs; mm++ )
@@ -936,11 +933,8 @@
 
         num_glyphs = FT_NEXT_ULONG( p );
 
-        /* overflow check */
-        if ( p + 2 * num_glyphs < p )
-          goto Failure;
-
-        if ( p + 2 * num_glyphs > p_limit )
+        /* overflow check for p + 2 * num_glyphs */
+        if ( num_glyphs > ( p_limit - p ) / 2 )
           goto NoBitmap;
 
         for ( mm = 0; mm < num_glyphs; mm++ )
-- 
1.7.10.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]