1 From b122edcb68ff05bb6eb22f6e50423e7f1050841b Mon Sep 17 00:00:00 2001
2 From: Larry Jones <lawrence.jones@siemens.com>
3 Date: Thu, 21 Oct 2010 10:08:16 +0200
4 Subject: [PATCH] Fix for CVE-2010-3846
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 Mallformed RCS revision (delete after the end of input file, or overlayed
10 deleted regions) screws output file image size computation. This leads to
11 write attempt after the allocated memory opening hiden memory corruption
14 Signed-off-by: Petr Písař <ppisar@redhat.com>
16 src/rcs.c | 52 +++++++++++++++++++++++++++++-----------------------
17 1 files changed, 29 insertions(+), 23 deletions(-)
19 diff --git a/src/rcs.c b/src/rcs.c
20 index 7d0d078..2f88f85 100644
23 @@ -7128,7 +7128,7 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
24 struct deltafrag *dfhead;
25 struct deltafrag **dftail;
27 - unsigned long numlines, lastmodline, offset;
28 + unsigned long numlines, offset;
29 struct linevector lines;
32 @@ -7202,12 +7202,12 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
34 /* New temp data structure to hold new org before
35 copy back into original structure. */
36 - lines.nlines = lines.lines_alloced = numlines;
37 + lines.lines_alloced = numlines;
38 lines.vector = xmalloc (numlines * sizeof *lines.vector);
40 /* We changed the list order to first to last -- so the
41 list never gets larger than the size numlines. */
45 /* offset created when adding/removing lines
46 between new and original structure */
47 @@ -7216,25 +7216,24 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
48 for (df = dfhead; df != NULL; )
51 - unsigned long deltaend;
52 + unsigned long newpos = df->pos - offset;
54 - if (df->pos > orig_lines->nlines)
55 + if (newpos < lines.nlines || newpos > numlines)
58 /* On error, just free the rest of the list. */
61 - /* Here we need to get to the line where the next insert will
62 + /* Here we need to get to the line where the next change will
63 begin, which is DF->pos in ORIG_LINES. We will fill up to
64 DF->pos - OFFSET in LINES with original items. */
65 - for (deltaend = df->pos - offset;
66 - lastmodline < deltaend;
68 + while (lines.nlines < newpos)
70 /* we need to copy from the orig structure into new one */
71 - lines.vector[lastmodline] =
72 - orig_lines->vector[lastmodline + offset];
73 - lines.vector[lastmodline]->refcount++;
74 + lines.vector[lines.nlines] =
75 + orig_lines->vector[lines.nlines + offset];
76 + lines.vector[lines.nlines]->refcount++;
81 @@ -7246,7 +7245,12 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
87 + if (newpos + df->nlines > numlines)
92 textend = df->new_lines + df->len;
94 nextline_text = df->new_lines;
95 @@ -7271,8 +7275,7 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
96 q->has_newline = nextline_newline;
98 memcpy (q->text, nextline_text, nextline_len);
99 - lines.vector[lastmodline++] = q;
101 + lines.vector[lines.nlines++] = q;
103 nextline_text = (char *)p + 1;
104 nextline_newline = 0;
105 @@ -7286,11 +7289,11 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
106 q->has_newline = nextline_newline;
108 memcpy (q->text, nextline_text, nextline_len);
109 - lines.vector[lastmodline++] = q;
110 + lines.vector[lines.nlines++] = q;
112 /* For each line we add the offset between the #'s
115 + offset -= df->nlines;
119 @@ -7301,7 +7304,9 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
120 if (df->pos + df->nlines > orig_lines->nlines)
124 for (ln = df->pos; ln < df->pos + df->nlines; ++ln)
126 if (orig_lines->vector[ln]->refcount > 1)
127 /* Annotate needs this but, since the original
128 * vector is disposed of before returning from
129 @@ -7309,6 +7314,8 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
130 * there are multiple references.
132 orig_lines->vector[ln]->vers = delvers;
138 @@ -7328,21 +7335,20 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
141 /* add the rest of the remaining lines to the data vector */
142 - for (; lastmodline < numlines; lastmodline++)
143 + while (lines.nlines < numlines)
145 /* we need to copy from the orig structure into new one */
146 - lines.vector[lastmodline] = orig_lines->vector[lastmodline
147 + lines.vector[lines.nlines] = orig_lines->vector[lines.nlines
149 - lines.vector[lastmodline]->refcount++;
150 + lines.vector[lines.nlines]->refcount++;
154 /* Move the lines vector to the original structure for output,
155 * first deleting the old.
157 linevector_free (orig_lines);
158 - orig_lines->vector = lines.vector;
159 - orig_lines->lines_alloced = numlines;
160 - orig_lines->nlines = lines.nlines;
161 + *orig_lines = lines;