5de29b
commit 41488498b6d9440ee66ab033808cce8323bba7ac
5de29b
Author: Florian Weimer <fweimer@redhat.com>
5de29b
Date:   Wed Sep 3 19:45:43 2014 +0200
5de29b
5de29b
    CVE-2014-6040: Crashes on invalid input in IBM gconv modules [BZ #17325]
5de29b
    
5de29b
    These changes are based on the fix for BZ #14134 in commit
5de29b
    6e230d11837f3ae7b375ea69d7905f0d18eb79e5.
5de29b
12745e
diff --git glibc-2.17-c758a686/iconvdata/Makefile glibc-2.17-c758a686/iconvdata/Makefile
5de29b
index 0a410a1..b6327d6 100644
12745e
--- glibc-2.17-c758a686/iconvdata/Makefile
12745e
+++ glibc-2.17-c758a686/iconvdata/Makefile
5de29b
@@ -297,6 +297,7 @@ $(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
5de29b
 $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
5de29b
 			 $(addprefix $(objpfx),$(modules.so)) \
5de29b
 			 $(common-objdir)/iconv/iconv_prog TESTS
5de29b
+	iconv_modules="$(modules)" \
5de29b
 	$(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@
5de29b
 
5de29b
 $(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
12745e
diff --git glibc-2.17-c758a686/iconvdata/ibm1364.c glibc-2.17-c758a686/iconvdata/ibm1364.c
5de29b
index 0b5484f..cf80993 100644
12745e
--- glibc-2.17-c758a686/iconvdata/ibm1364.c
12745e
+++ glibc-2.17-c758a686/iconvdata/ibm1364.c
5de29b
@@ -221,7 +221,8 @@ enum
5de29b
 	  ++rp2;							      \
5de29b
 									      \
5de29b
 	uint32_t res;							      \
5de29b
-	if (__builtin_expect (ch < rp2->start, 0)			      \
5de29b
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
5de29b
+	    || __builtin_expect (ch < rp2->start, 0)			      \
5de29b
 	    || (res = DB_TO_UCS4[ch + rp2->idx],			      \
5de29b
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
5de29b
 	  {								      \
12745e
diff --git glibc-2.17-c758a686/iconvdata/ibm932.c glibc-2.17-c758a686/iconvdata/ibm932.c
5de29b
index f5dca59..aa69d65 100644
12745e
--- glibc-2.17-c758a686/iconvdata/ibm932.c
12745e
+++ glibc-2.17-c758a686/iconvdata/ibm932.c
5de29b
@@ -74,11 +74,12 @@
5de29b
 	  }								      \
5de29b
 									      \
5de29b
 	ch = (ch * 0x100) + inptr[1];					      \
5de29b
+	/* ch was less than 0xfd.  */					      \
5de29b
+	assert (ch < 0xfd00);						      \
5de29b
 	while (ch > rp2->end)						      \
5de29b
 	  ++rp2;							      \
5de29b
 									      \
5de29b
-	if (__builtin_expect (rp2 == NULL, 0)				      \
5de29b
-	    || __builtin_expect (ch < rp2->start, 0)			      \
5de29b
+	if (__builtin_expect (ch < rp2->start, 0)			      \
5de29b
 	    || (res = __ibm932db_to_ucs4[ch + rp2->idx],		      \
5de29b
 	    __builtin_expect (res, '\1') == 0 && ch !=0))		      \
5de29b
 	  {								      \
12745e
diff --git glibc-2.17-c758a686/iconvdata/ibm933.c glibc-2.17-c758a686/iconvdata/ibm933.c
5de29b
index f46dfb5..461fb5e 100644
12745e
--- glibc-2.17-c758a686/iconvdata/ibm933.c
12745e
+++ glibc-2.17-c758a686/iconvdata/ibm933.c
5de29b
@@ -162,7 +162,7 @@ enum
5de29b
 	while (ch > rp2->end)						      \
5de29b
 	  ++rp2;							      \
5de29b
 									      \
5de29b
-	if (__builtin_expect (rp2 == NULL, 0)				      \
5de29b
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
5de29b
 	    || __builtin_expect (ch < rp2->start, 0)			      \
5de29b
 	    || (res = __ibm933db_to_ucs4[ch + rp2->idx],		      \
5de29b
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
12745e
diff --git glibc-2.17-c758a686/iconvdata/ibm935.c glibc-2.17-c758a686/iconvdata/ibm935.c
5de29b
index a8e4e6c..132d816 100644
12745e
--- glibc-2.17-c758a686/iconvdata/ibm935.c
12745e
+++ glibc-2.17-c758a686/iconvdata/ibm935.c
5de29b
@@ -162,7 +162,7 @@ enum
5de29b
 	while (ch > rp2->end)						      \
5de29b
 	  ++rp2;							      \
5de29b
 									      \
5de29b
-	if (__builtin_expect (rp2 == NULL, 0)				      \
5de29b
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
5de29b
 	    || __builtin_expect (ch < rp2->start, 0)			      \
5de29b
 	    || (res = __ibm935db_to_ucs4[ch + rp2->idx],		      \
5de29b
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
12745e
diff --git glibc-2.17-c758a686/iconvdata/ibm937.c glibc-2.17-c758a686/iconvdata/ibm937.c
5de29b
index 239be61..69b154d 100644
12745e
--- glibc-2.17-c758a686/iconvdata/ibm937.c
12745e
+++ glibc-2.17-c758a686/iconvdata/ibm937.c
5de29b
@@ -162,7 +162,7 @@ enum
5de29b
 	while (ch > rp2->end)						      \
5de29b
 	  ++rp2;							      \
5de29b
 									      \
5de29b
-	if (__builtin_expect (rp2 == NULL, 0)				      \
5de29b
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
5de29b
 	    || __builtin_expect (ch < rp2->start, 0)			      \
5de29b
 	    || (res = __ibm937db_to_ucs4[ch + rp2->idx],		      \
5de29b
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
12745e
diff --git glibc-2.17-c758a686/iconvdata/ibm939.c glibc-2.17-c758a686/iconvdata/ibm939.c
5de29b
index 5d0db36..9936e2c 100644
12745e
--- glibc-2.17-c758a686/iconvdata/ibm939.c
12745e
+++ glibc-2.17-c758a686/iconvdata/ibm939.c
5de29b
@@ -162,7 +162,7 @@ enum
5de29b
 	while (ch > rp2->end)						      \
5de29b
 	  ++rp2;							      \
5de29b
 									      \
5de29b
-	if (__builtin_expect (rp2 == NULL, 0)				      \
5de29b
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
5de29b
 	    || __builtin_expect (ch < rp2->start, 0)			      \
5de29b
 	    || (res = __ibm939db_to_ucs4[ch + rp2->idx],		      \
5de29b
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
12745e
diff --git glibc-2.17-c758a686/iconvdata/ibm943.c glibc-2.17-c758a686/iconvdata/ibm943.c
5de29b
index be0c14f..c5d5742 100644
12745e
--- glibc-2.17-c758a686/iconvdata/ibm943.c
12745e
+++ glibc-2.17-c758a686/iconvdata/ibm943.c
5de29b
@@ -75,11 +75,12 @@
5de29b
 	  }								      \
5de29b
 									      \
5de29b
 	ch = (ch * 0x100) + inptr[1];					      \
5de29b
+	/* ch was less than 0xfd.  */					      \
5de29b
+	assert (ch < 0xfd00);						      \
5de29b
 	while (ch > rp2->end)						      \
5de29b
 	  ++rp2;							      \
5de29b
 									      \
5de29b
-	if (__builtin_expect (rp2 == NULL, 0)				      \
5de29b
-	    || __builtin_expect (ch < rp2->start, 0)			      \
5de29b
+	if (__builtin_expect (ch < rp2->start, 0)			      \
5de29b
 	    || (res = __ibm943db_to_ucs4[ch + rp2->idx],		      \
5de29b
 	    __builtin_expect (res, '\1') == 0 && ch !=0))		      \
5de29b
 	  {								      \
12745e
diff --git glibc-2.17-c758a686/iconvdata/run-iconv-test.sh glibc-2.17-c758a686/iconvdata/run-iconv-test.sh
5de29b
index c98c929..5dfb69f 100755
12745e
--- glibc-2.17-c758a686/iconvdata/run-iconv-test.sh
12745e
+++ glibc-2.17-c758a686/iconvdata/run-iconv-test.sh
5de29b
@@ -184,6 +184,24 @@ while read utf8 from filename; do
5de29b
 
5de29b
 done < TESTS2
5de29b
 
5de29b
+# Check for crashes in decoders.
5de29b
+printf '\016\377\377\377\377\377\377\377' > $temp1
5de29b
+for from in $iconv_modules ; do
5de29b
+    echo $ac_n "test decoder $from $ac_c"
5de29b
+    PROG=`eval echo $ICONV`
5de29b
+    if $PROG < $temp1 >/dev/null 2>&1 ; then
5de29b
+	: # fall through
5de29b
+    else
5de29b
+	status=$?
5de29b
+	if test $status -gt 1 ; then
5de29b
+	    echo "/FAILED"
5de29b
+	    failed=1
5de29b
+	    continue
5de29b
+	fi
5de29b
+    fi
5de29b
+    echo "OK"
5de29b
+done
5de29b
+
5de29b
 exit $failed
5de29b
 # Local Variables:
5de29b
 #  mode:shell-script