]>
Commit | Line | Data |
---|---|---|
4690e8e8 AK |
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 | |
3 | comment #12. | |
4 | . | |
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. | |
13 | . | |
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. | |
20 | . | |
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 | |
23 | function instead. | |
24 | . | |
25 | With this patch instead of the original: | |
26 | . | |
27 | - `make check` still passes | |
28 | . | |
29 | - The reproducer script completes successfully with exit code 0 | |
30 | . | |
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 | |
36 | --- | |
37 | # HG changeset patch | |
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 | |
44 | ||
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 | |
48 | @@ -615,11 +615,14 @@ | |
49 | */ | |
50 | ||
51 | static int | |
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); | |
55 | ||
56 | static int | |
57 | -yaml_parser_unroll_indent(yaml_parser_t *parser, int column); | |
58 | +yaml_parser_unroll_indent(yaml_parser_t *parser, size_t column); | |
59 | + | |
60 | +static int | |
61 | +yaml_parser_reset_indent(yaml_parser_t *parser); | |
62 | ||
63 | /* | |
64 | * Token fetchers. | |
65 | @@ -1206,7 +1209,7 @@ | |
66 | */ | |
67 | ||
68 | static int | |
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) | |
72 | { | |
73 | yaml_token_t token; | |
74 | @@ -1216,7 +1219,7 @@ | |
75 | if (parser->flow_level) | |
76 | return 1; | |
77 | ||
78 | - if (parser->indent < column) | |
79 | + if (parser->indent == -1 || parser->indent < column) | |
80 | { | |
81 | /* | |
82 | * Push the current indentation level to the stack and set the new | |
83 | @@ -1254,7 +1257,7 @@ | |
84 | ||
85 | ||
86 | static int | |
87 | -yaml_parser_unroll_indent(yaml_parser_t *parser, int column) | |
88 | +yaml_parser_unroll_indent(yaml_parser_t *parser, size_t column) | |
89 | { | |
90 | yaml_token_t token; | |
91 | ||
92 | @@ -1263,6 +1266,15 @@ | |
93 | if (parser->flow_level) | |
94 | return 1; | |
95 | ||
96 | + /* | |
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. | |
100 | + */ | |
101 | + | |
102 | + if (parser->indent < 0) | |
103 | + return 1; | |
104 | + | |
105 | /* Loop through the intendation levels in the stack. */ | |
106 | ||
107 | while (parser->indent > column) | |
108 | @@ -1283,6 +1295,41 @@ | |
109 | } | |
110 | ||
111 | /* | |
112 | + * Pop indentation levels from the indents stack until the current | |
113 | + * level resets to -1. For each intendation level, append the | |
114 | + * BLOCK-END token. | |
115 | + */ | |
116 | + | |
117 | +static int | |
118 | +yaml_parser_reset_indent(yaml_parser_t *parser) | |
119 | +{ | |
120 | + yaml_token_t token; | |
121 | + | |
122 | + /* In the flow context, do nothing. */ | |
123 | + | |
124 | + if (parser->flow_level) | |
125 | + return 1; | |
126 | + | |
127 | + /* Loop through the intendation levels in the stack. */ | |
128 | + | |
129 | + while (parser->indent > -1) | |
130 | + { | |
131 | + /* Create a token and append it to the queue. */ | |
132 | + | |
133 | + TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark); | |
134 | + | |
135 | + if (!ENQUEUE(parser, parser->tokens, token)) | |
136 | + return 0; | |
137 | + | |
138 | + /* Pop the indentation level. */ | |
139 | + | |
140 | + parser->indent = POP(parser, parser->indents); | |
141 | + } | |
142 | + | |
143 | + return 1; | |
144 | +} | |
145 | + | |
146 | +/* | |
147 | * Initialize the scanner and produce the STREAM-START token. | |
148 | */ | |
149 | ||
150 | @@ -1338,7 +1385,7 @@ | |
151 | ||
152 | /* Reset the indentation level. */ | |
153 | ||
154 | - if (!yaml_parser_unroll_indent(parser, -1)) | |
155 | + if (!yaml_parser_reset_indent(parser)) | |
156 | return 0; | |
157 | ||
158 | /* Reset simple keys. */ | |
159 | @@ -1369,7 +1416,7 @@ | |
160 | ||
161 | /* Reset the indentation level. */ | |
162 | ||
163 | - if (!yaml_parser_unroll_indent(parser, -1)) | |
164 | + if (!yaml_parser_reset_indent(parser)) | |
165 | return 0; | |
166 | ||
167 | /* Reset simple keys. */ | |
168 | @@ -1407,7 +1454,7 @@ | |
169 | ||
170 | /* Reset the indentation level. */ | |
171 | ||
172 | - if (!yaml_parser_unroll_indent(parser, -1)) | |
173 | + if (!yaml_parser_reset_indent(parser)) | |
174 | return 0; | |
175 | ||
176 | /* Reset simple keys. */ |