Blame SOURCES/cvs-1.11.23-cve-2010-3846.patch

36e843
From b122edcb68ff05bb6eb22f6e50423e7f1050841b Mon Sep 17 00:00:00 2001
36e843
From: Larry Jones <lawrence.jones@siemens.com>
36e843
Date: Thu, 21 Oct 2010 10:08:16 +0200
36e843
Subject: [PATCH] Fix for CVE-2010-3846
36e843
MIME-Version: 1.0
36e843
Content-Type: text/plain; charset=UTF-8
36e843
Content-Transfer-Encoding: 8bit
36e843
36e843
Mallformed RCS revision (delete after the end of input file, or overlayed
36e843
deleted regions) screws output file image size computation. This leads to
36e843
write attempt after the allocated memory opening hiden memory corruption
36e843
driven by CVS server.
36e843
36e843
Signed-off-by: Petr Písař <ppisar@redhat.com>
36e843
---
36e843
 src/rcs.c |   52 +++++++++++++++++++++++++++++-----------------------
36e843
 1 files changed, 29 insertions(+), 23 deletions(-)
36e843
36e843
diff --git a/src/rcs.c b/src/rcs.c
36e843
index 7d0d078..2f88f85 100644
36e843
--- a/src/rcs.c
36e843
+++ b/src/rcs.c
36e843
@@ -7128,7 +7128,7 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
     struct deltafrag *dfhead;
36e843
     struct deltafrag **dftail;
36e843
     struct deltafrag *df;
36e843
-    unsigned long numlines, lastmodline, offset;
36e843
+    unsigned long numlines, offset;
36e843
     struct linevector lines;
36e843
     int err;
36e843
 
36e843
@@ -7202,12 +7202,12 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
 
36e843
     /* New temp data structure to hold new org before
36e843
        copy back into original structure. */
36e843
-    lines.nlines = lines.lines_alloced = numlines;
36e843
+    lines.lines_alloced = numlines;
36e843
     lines.vector = xmalloc (numlines * sizeof *lines.vector);
36e843
 
36e843
     /* We changed the list order to first to last -- so the
36e843
        list never gets larger than the size numlines. */
36e843
-    lastmodline = 0; 
36e843
+    lines.nlines = 0; 
36e843
 
36e843
     /* offset created when adding/removing lines
36e843
        between new and original structure */
36e843
@@ -7216,25 +7216,24 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
     for (df = dfhead; df != NULL; )
36e843
     {
36e843
 	unsigned int ln;
36e843
-	unsigned long deltaend;
36e843
+	unsigned long newpos = df->pos - offset;
36e843
 
36e843
-	if (df->pos > orig_lines->nlines)
36e843
+	if (newpos < lines.nlines || newpos > numlines)
36e843
 	    err = 1;
36e843
 
36e843
 	/* On error, just free the rest of the list.  */
36e843
 	if (!err)
36e843
 	{
36e843
-	    /* Here we need to get to the line where the next insert will
36e843
+	    /* Here we need to get to the line where the next change will
36e843
 	       begin, which is DF->pos in ORIG_LINES.  We will fill up to
36e843
 	       DF->pos - OFFSET in LINES with original items.  */
36e843
-	    for (deltaend = df->pos - offset;
36e843
-		 lastmodline < deltaend;
36e843
-		 lastmodline++)
36e843
+	    while (lines.nlines < newpos)
36e843
 	    {
36e843
 		/* we need to copy from the orig structure into new one */
36e843
-		lines.vector[lastmodline] =
36e843
-			orig_lines->vector[lastmodline + offset];
36e843
-		lines.vector[lastmodline]->refcount++;
36e843
+		lines.vector[lines.nlines] =
36e843
+			orig_lines->vector[lines.nlines + offset];
36e843
+		lines.vector[lines.nlines]->refcount++;
36e843
+		lines.nlines++;
36e843
 	    }
36e843
 
36e843
 	    switch (df->type)
36e843
@@ -7246,7 +7245,12 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
 		    struct line *q;
36e843
 		    int nextline_newline;
36e843
 		    size_t nextline_len;
36e843
-		
36e843
+
36e843
+		    if (newpos + df->nlines > numlines)
36e843
+		    {
36e843
+			err = 1;
36e843
+			break;
36e843
+		    }
36e843
 		    textend = df->new_lines + df->len;
36e843
 		    nextline_newline = 0;
36e843
 		    nextline_text = df->new_lines;
36e843
@@ -7271,8 +7275,7 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
 			    q->has_newline = nextline_newline;
36e843
 			    q->refcount = 1;
36e843
 			    memcpy (q->text, nextline_text, nextline_len);
36e843
-			    lines.vector[lastmodline++] = q;
36e843
-			    offset--;
36e843
+			    lines.vector[lines.nlines++] = q;
36e843
 		    
36e843
 			    nextline_text = (char *)p + 1;
36e843
 			    nextline_newline = 0;
36e843
@@ -7286,11 +7289,11 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
 		    q->has_newline = nextline_newline;
36e843
 		    q->refcount = 1;
36e843
 		    memcpy (q->text, nextline_text, nextline_len);
36e843
-		    lines.vector[lastmodline++] = q;
36e843
+		    lines.vector[lines.nlines++] = q;
36e843
 
36e843
 		    /* For each line we add the offset between the #'s
36e843
 		       decreases. */
36e843
-		    offset--;
36e843
+		    offset -= df->nlines;
36e843
 		    break;
36e843
 		}
36e843
 
36e843
@@ -7301,7 +7304,9 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
 		    if (df->pos + df->nlines > orig_lines->nlines)
36e843
 			err = 1;
36e843
 		    else if (delvers)
36e843
+		    {
36e843
 			for (ln = df->pos; ln < df->pos + df->nlines; ++ln)
36e843
+			{
36e843
 			    if (orig_lines->vector[ln]->refcount > 1)
36e843
 				/* Annotate needs this but, since the original
36e843
 				 * vector is disposed of before returning from
36e843
@@ -7309,6 +7314,8 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
 				 * there are multiple references.
36e843
 				 */
36e843
 				orig_lines->vector[ln]->vers = delvers;
36e843
+			}
36e843
+		    }
36e843
 		    break;
36e843
 	    }
36e843
 	}
36e843
@@ -7328,21 +7335,20 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
36e843
     else
36e843
     {
36e843
 	/* add the rest of the remaining lines to the data vector */
36e843
-	for (; lastmodline < numlines; lastmodline++)
36e843
+	while (lines.nlines < numlines)
36e843
 	{
36e843
 	    /* we need to copy from the orig structure into new one */
36e843
-	    lines.vector[lastmodline] = orig_lines->vector[lastmodline
36e843
+	    lines.vector[lines.nlines] = orig_lines->vector[lines.nlines
36e843
 							   + offset];
36e843
-	    lines.vector[lastmodline]->refcount++;
36e843
+	    lines.vector[lines.nlines]->refcount++;
36e843
+	    lines.nlines++;
36e843
 	}
36e843
 
36e843
 	/* Move the lines vector to the original structure for output,
36e843
 	 * first deleting the old.
36e843
 	 */
36e843
 	linevector_free (orig_lines);
36e843
-	orig_lines->vector = lines.vector;
36e843
-	orig_lines->lines_alloced = numlines;
36e843
-	orig_lines->nlines = lines.nlines;
36e843
+	*orig_lines = lines;
36e843
     }
36e843
 
36e843
     return !err;
36e843
-- 
36e843
1.7.2.3
36e843