This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix cpplib buffer overrun


cpplib (cpp_token_len) thinks the maximum length of a non-identifier, 
non-literal token is 4 bytes, which does not allow for various C++ named 
operators.  Thus if an operator such as xor_eq is stringized with 
cpplib's buffers at exactly the right point before the end of allocated 
space for this to cause it to decide there is enough space on the basis of 
the 4 byte length, when there isn't on the basis of the 6 byte length, 
then a buffer overrun can occur.  Various cases other than stringizing can 
also be affected.  (Because of the dependence on the exact details of 
internal buffers, a particular testcase may not reliably show the problem 
in all cases.)

This patch fixes this bug.  Bootstrapped with no regressions on 
i686-pc-linux-gnu.  Applied to mainline.

Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 142274)
+++ gcc/testsuite/ChangeLog	(working copy)
@@ -1,3 +1,7 @@
+2008-11-29  Joseph Myers  <joseph@codesourcery.com>
+
+	* g++.dg/cpp/stringop-1.C: New test.
+
 2008-11-29  Eric Botcazou  <ebotcazou@adacore.com>
 
 	* gnat.dg/test_version.adb: Adjust to new string length.
Index: gcc/testsuite/g++.dg/cpp/stringop-1.C
===================================================================
--- gcc/testsuite/g++.dg/cpp/stringop-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp/stringop-1.C	(revision 0)
@@ -0,0 +1,29 @@
+/* Test for buffer overrun stringizing named operators longer than 4
+   characters.  */
+/* { dg-do compile } */
+
+#define str(x) #x
+#define var(v,a,b,c,d) static const char v##a##b##c##d[] = str(xor_eq)
+#define var1(v,a,b,c)							\
+  var(v,a,b,c,0); var(v,a,b,c,1); var(v,a,b,c,2); var(v,a,b,c,3); 	\
+  var(v,a,b,c,4); var(v,a,b,c,5); var(v,a,b,c,6); var(v,a,b,c,7); 	\
+  var(v,a,b,c,8); var(v,a,b,c,9)
+#define var2(v,a,b)						\
+  var1(v,a,b,0); var1(v,a,b,1); var1(v,a,b,2); var1(v,a,b,3);	\
+  var1(v,a,b,4); var1(v,a,b,5); var1(v,a,b,6); var1(v,a,b,7);	\
+  var1(v,a,b,8); var1(v,a,b,9)
+#define var3(v,a)					\
+  var2(v,a,0); var2(v,a,1); var2(v,a,2); var2(v,a,3);	\
+  var2(v,a,4); var2(v,a,5); var2(v,a,6); var2(v,a,7);	\
+  var2(v,a,8); var2(v,a,9)
+
+var3(v,0);
+var3(v,1);
+var3(v,2);
+var3(v,3);
+var3(v,4);
+var3(v,5);
+var3(v,6);
+var3(v,7);
+var3(v,8);
+var3(v,9);
Index: libcpp/ChangeLog
===================================================================
--- libcpp/ChangeLog	(revision 142274)
+++ libcpp/ChangeLog	(working copy)
@@ -1,3 +1,7 @@
+2008-11-29  Joseph Myers  <joseph@codesourcery.com>
+
+	* lex.c (cpp_token_len): Use 6 as default length.
+
 2008-10-31  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
 	* expr.c (struct op): Add location.
Index: libcpp/lex.c
===================================================================
--- libcpp/lex.c	(revision 142264)
+++ libcpp/lex.c	(working copy)
@@ -1362,7 +1362,7 @@
 
   switch (TOKEN_SPELL (token))
     {
-    default:		len = 4;				break;
+    default:		len = 6;				break;
     case SPELL_LITERAL:	len = token->val.str.len;		break;
     case SPELL_IDENT:	len = NODE_LEN (token->val.node) * 10;	break;
     }

-- 
Joseph S. Myers
joseph@codesourcery.com

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]