1 Description: CVE-2013-6393: yaml_parser-{un,}roll-indent: fix int overflow in column argument
2 This expands upon the original indent column overflow patch from
5 The default parser indention is represented as an indention of -1.
6 The original patch only modified the type of the column parameter to
7 the roll/unroll functions, changing it from int to size_t to guard
8 against integer overflow. However, there are code paths that call
9 yaml_parser_unroll_indent with a column of -1 in order to reset the
10 parser back to the initial indention. Since the column is now of
11 type size_t and thus unsigned, passing a column value of -1 caused
12 the column to underflow in this case.
14 This new patch modifies the roll/unroll functions to handle the -1
15 indent as a special case. In addition, it adds a new function,
16 yaml_parser_reset_indent. It is nearly an exact copy of
17 yaml_parser_unroll_indent, except it does not take a column
18 parameter. Instead it unrolls to a literal -1 indention, which does
19 not suffer from the underflow.
21 Code paths that previously called yaml_parser_unroll_indent with a
22 column of -1 are updated to call the new yaml_parser_reset_indent
25 With this patch instead of the original:
27 - `make check` still passes
29 - The reproducer script completes successfully with exit code 0
31 - The issue raised by John Haxby has been corrected and exits with SUCCESS
32 Origin: https://bugzilla.redhat.com/show_bug.cgi?id=1033990
33 Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1033990
34 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=737076
35 Last-Update: 2014-01-29
38 # User John Eckersberg <jeckersb@redhat.com>
39 # Date 1390870108 18000
40 # Mon Jan 27 19:48:28 2014 -0500
41 # Node ID 7179aa474f31e73834adda26b77bfc25bfe5143d
42 # Parent 3e6507fa0c26d20c09f8f468f2bd04aa2fd1b5b5
43 yaml_parser-{un,}roll-indent: fix int overflow in column argument
45 diff -r 3e6507fa0c26 -r 7179aa474f31 src/scanner.c
46 --- a/src/scanner.c Mon Dec 24 03:51:32 2012 +0000
47 +++ b/src/scanner.c Mon Jan 27 19:48:28 2014 -0500
52 -yaml_parser_roll_indent(yaml_parser_t *parser, int column,
53 +yaml_parser_roll_indent(yaml_parser_t *parser, size_t column,
54 int number, yaml_token_type_t type, yaml_mark_t mark);
57 -yaml_parser_unroll_indent(yaml_parser_t *parser, int column);
58 +yaml_parser_unroll_indent(yaml_parser_t *parser, size_t column);
61 +yaml_parser_reset_indent(yaml_parser_t *parser);
69 -yaml_parser_roll_indent(yaml_parser_t *parser, int column,
70 +yaml_parser_roll_indent(yaml_parser_t *parser, size_t column,
71 int number, yaml_token_type_t type, yaml_mark_t mark)
75 if (parser->flow_level)
78 - if (parser->indent < column)
79 + if (parser->indent == -1 || parser->indent < column)
82 * Push the current indentation level to the stack and set the new
87 -yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
88 +yaml_parser_unroll_indent(yaml_parser_t *parser, size_t column)
92 @@ -1263,6 +1266,15 @@
93 if (parser->flow_level)
97 + * column is unsigned and parser->indent is signed, so if
98 + * parser->indent is less than zero the conditional in the while
99 + * loop below is incorrect. Guard against that.
102 + if (parser->indent < 0)
105 /* Loop through the intendation levels in the stack. */
107 while (parser->indent > column)
108 @@ -1283,6 +1295,41 @@
112 + * Pop indentation levels from the indents stack until the current
113 + * level resets to -1. For each intendation level, append the
118 +yaml_parser_reset_indent(yaml_parser_t *parser)
120 + yaml_token_t token;
122 + /* In the flow context, do nothing. */
124 + if (parser->flow_level)
127 + /* Loop through the intendation levels in the stack. */
129 + while (parser->indent > -1)
131 + /* Create a token and append it to the queue. */
133 + TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark);
135 + if (!ENQUEUE(parser, parser->tokens, token))
138 + /* Pop the indentation level. */
140 + parser->indent = POP(parser, parser->indents);
147 * Initialize the scanner and produce the STREAM-START token.
150 @@ -1338,7 +1385,7 @@
152 /* Reset the indentation level. */
154 - if (!yaml_parser_unroll_indent(parser, -1))
155 + if (!yaml_parser_reset_indent(parser))
158 /* Reset simple keys. */
159 @@ -1369,7 +1416,7 @@
161 /* Reset the indentation level. */
163 - if (!yaml_parser_unroll_indent(parser, -1))
164 + if (!yaml_parser_reset_indent(parser))
167 /* Reset simple keys. */
168 @@ -1407,7 +1454,7 @@
170 /* Reset the indentation level. */
172 - if (!yaml_parser_unroll_indent(parser, -1))
173 + if (!yaml_parser_reset_indent(parser))
176 /* Reset simple keys. */