70e4bf
From 6149f39ada50f7ebc6b0cb7756490a0fea967bd1 Mon Sep 17 00:00:00 2001
70e4bf
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
70e4bf
Date: Fri, 4 Jan 2013 13:33:11 +0100
70e4bf
Subject: [PATCH 1/2] Fix CVE-2012-6089
70e4bf
70e4bf
Upstream fix ported to 5.10.2:
70e4bf
70e4bf
From a9a6fc8a2a9cf3b9154b490a4b1ffaa8be4d723c Mon Sep 17 00:00:00 2001
70e4bf
From: Jan Wielemaker <j.wielemaker@cs.vu.nl>
70e4bf
Date: Sun, 16 Dec 2012 18:13:17 +0100
70e4bf
Subject: [PATCH] FIXED: Possible buffer overrun in patch canonisation code.
70e4bf
70e4bf
Pushes pointers on an automatic array without checking for overflow.
70e4bf
Can be used for DoS attacks.  Will be extremely hard to make it execute
70e4bf
arbitrary code.
70e4bf
---
70e4bf
 src/pl-buffer.h |  2 ++
70e4bf
 src/pl-os.c     | 19 +++++++++++--------
70e4bf
 2 files changed, 13 insertions(+), 8 deletions(-)
70e4bf
70e4bf
diff --git a/src/pl-buffer.h b/src/pl-buffer.h
70e4bf
index d4149c1..000bca5 100644
70e4bf
--- a/src/pl-buffer.h
70e4bf
+++ b/src/pl-buffer.h
70e4bf
@@ -79,6 +79,8 @@ void	growBuffer(Buffer b, size_t minfree);
70e4bf
 				  sizeof((b)->static_buffer))
70e4bf
 #define emptyBuffer(b)           ((b)->top  = (b)->base)
70e4bf
 #define isEmptyBuffer(b)         ((b)->top == (b)->base)
70e4bf
+#define popBuffer(b,type) \
70e4bf
+	((b)->top -= sizeof(type), *(type*)(b)->top)
70e4bf
 
70e4bf
 #define discardBuffer(b) \
70e4bf
 	do \
70e4bf
diff --git a/src/pl-os.c b/src/pl-os.c
70e4bf
index c6aaefc..4d008d6 100644
70e4bf
--- a/src/pl-os.c
70e4bf
+++ b/src/pl-os.c
70e4bf
@@ -1081,8 +1081,7 @@ cleanupExpand(void)
70e4bf
 char *
70e4bf
 canoniseFileName(char *path)
70e4bf
 { char *out = path, *in = path, *start = path;
70e4bf
-  char *osave[100];
70e4bf
-  int  osavep = 0;
70e4bf
+  tmp_buffer saveb;
70e4bf
 
70e4bf
 #ifdef O_HASDRIVES			/* C: */
70e4bf
   if ( in[1] == ':' && isLetter(in[0]) )
70e4bf
@@ -1110,7 +1109,8 @@ canoniseFileName(char *path)
70e4bf
     in += 2;
70e4bf
   if ( in[0] == '/' )
70e4bf
     *out++ = '/';
70e4bf
-  osave[osavep++] = out;
70e4bf
+  initBuffer(&saveb);
70e4bf
+  addBuffer(&saveb, out, char*);
70e4bf
 
70e4bf
   while(*in)
70e4bf
   { if (*in == '/')
70e4bf
@@ -1126,15 +1126,15 @@ canoniseFileName(char *path)
70e4bf
 	  }
70e4bf
 	  if ( in[2] == EOS )		/* delete trailing /. */
70e4bf
 	  { *out = EOS;
70e4bf
-	    return path;
70e4bf
+	    goto out;
70e4bf
 	  }
70e4bf
 	  if ( in[2] == '.' && (in[3] == '/' || in[3] == EOS) )
70e4bf
-	  { if ( osavep > 0 )		/* delete /foo/../ */
70e4bf
-	    { out = osave[--osavep];
70e4bf
+	  { if ( !isEmptyBuffer(&saveb) )		/* delete /foo/../ */
70e4bf
+	    { out = popBuffer(&saveb, char*);
70e4bf
 	      in += 3;
70e4bf
 	      if ( in[0] == EOS && out > start+1 )
70e4bf
 	      { out[-1] = EOS;		/* delete trailing / */
70e4bf
-		return path;
70e4bf
+		goto out;
70e4bf
 	      }
70e4bf
 	      goto again;
70e4bf
 	    } else if (	start[0] == '/' && out == start+1 )
70e4bf
@@ -1148,12 +1148,15 @@ canoniseFileName(char *path)
70e4bf
 	in++;
70e4bf
       if ( out > path && out[-1] != '/' )
70e4bf
 	*out++ = '/';
70e4bf
-      osave[osavep++] = out;
70e4bf
+      addBuffer(&saveb, out, char*);
70e4bf
     } else
70e4bf
       *out++ = *in++;
70e4bf
   }
70e4bf
   *out++ = *in++;
70e4bf
 
70e4bf
+out:
70e4bf
+  discardBuffer(&saveb);
70e4bf
+
70e4bf
   return path;
70e4bf
 }
70e4bf
 
70e4bf
-- 
70e4bf
1.7.11.7
70e4bf