Apply patch for CVE-2013-6393 [1] to fix heap-based buffer overflow when

parsing YAML tags.
Also apply a patch for hardenning the guards againt the issue

The only user in base in yaml is pkg(7) which uses the library a way that it is not affected

Submitted by:	delphij
Obtained from:	https://bugzilla.redhat.com/show_bug.cgi?id=1033990
MFC after:	3 days
Security:	CVE-2013-6393
This commit is contained in:
Baptiste Daroussin 2014-02-03 08:13:44 +00:00
commit 968ba8fe77
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=261431
2 changed files with 62 additions and 10 deletions

View File

@ -117,7 +117,12 @@ yaml_string_join(
YAML_DECLARE(int)
yaml_stack_extend(void **start, void **top, void **end)
{
void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
void *new_start;
if ((char *)*end - (char *)*start >= INT_MAX / 2)
return 0;
new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
if (!new_start) return 0;

View File

@ -615,11 +615,14 @@ yaml_parser_decrease_flow_level(yaml_parser_t *parser);
*/
static int
yaml_parser_roll_indent(yaml_parser_t *parser, int column,
yaml_parser_roll_indent(yaml_parser_t *parser, size_t column,
int number, yaml_token_type_t type, yaml_mark_t mark);
static int
yaml_parser_unroll_indent(yaml_parser_t *parser, int column);
yaml_parser_unroll_indent(yaml_parser_t *parser, size_t column);
static int
yaml_parser_reset_indent(yaml_parser_t *parser);
/*
* Token fetchers.
@ -1206,7 +1209,7 @@ yaml_parser_decrease_flow_level(yaml_parser_t *parser)
*/
static int
yaml_parser_roll_indent(yaml_parser_t *parser, int column,
yaml_parser_roll_indent(yaml_parser_t *parser, size_t column,
int number, yaml_token_type_t type, yaml_mark_t mark)
{
yaml_token_t token;
@ -1216,7 +1219,7 @@ yaml_parser_roll_indent(yaml_parser_t *parser, int column,
if (parser->flow_level)
return 1;
if (parser->indent < column)
if (parser->indent == -1 || parser->indent < column)
{
/*
* Push the current indentation level to the stack and set the new
@ -1254,7 +1257,51 @@ yaml_parser_roll_indent(yaml_parser_t *parser, int column,
static int
yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
yaml_parser_unroll_indent(yaml_parser_t *parser, size_t column)
{
yaml_token_t token;
/* In the flow context, do nothing. */
if (parser->flow_level)
return 1;
/*
* column is unsigned and parser->indent is signed, so if
* parser->indent is less than zero the conditional in the while
* loop below is incorrect. Guard against that.
*/
if (parser->indent < 0)
return 1;
/* Loop through the intendation levels in the stack. */
while (parser->indent > column)
{
/* Create a token and append it to the queue. */
TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark);
if (!ENQUEUE(parser, parser->tokens, token))
return 0;
/* Pop the indentation level. */
parser->indent = POP(parser, parser->indents);
}
return 1;
}
/*
* Pop indentation levels from the indents stack until the current
* level resets to -1. For each intendation level, append the
* BLOCK-END token.
*/
static int
yaml_parser_reset_indent(yaml_parser_t *parser)
{
yaml_token_t token;
@ -1265,7 +1312,7 @@ yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
/* Loop through the intendation levels in the stack. */
while (parser->indent > column)
while (parser->indent > -1)
{
/* Create a token and append it to the queue. */
@ -1338,7 +1385,7 @@ yaml_parser_fetch_stream_end(yaml_parser_t *parser)
/* Reset the indentation level. */
if (!yaml_parser_unroll_indent(parser, -1))
if (!yaml_parser_reset_indent(parser))
return 0;
/* Reset simple keys. */
@ -1369,7 +1416,7 @@ yaml_parser_fetch_directive(yaml_parser_t *parser)
/* Reset the indentation level. */
if (!yaml_parser_unroll_indent(parser, -1))
if (!yaml_parser_reset_indent(parser))
return 0;
/* Reset simple keys. */
@ -1407,7 +1454,7 @@ yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
/* Reset the indentation level. */
if (!yaml_parser_unroll_indent(parser, -1))
if (!yaml_parser_reset_indent(parser))
return 0;
/* Reset simple keys. */