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

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