Skip to content

Commit ead1e19

Browse files
mhiramatrostedt
authored andcommitted
lib/bootconfig: Fix a bug of breaking existing tree nodes
Fix a bug of breaking existing tree nodes by parsing the second and subsequent braces. Since the bootconfig parser uses the node.next field as a flag of current parent node, but this will break the existing tree if the same key node is specified again in the bootconfig. For example, the following bootconfig should be foo.buz and bar. foo bar foo { buz } However, when parsing the brace "{", it breaks foo->bar link by marking open-brace node. So the bootconfig unlinks bar from the bootconfig internal tree. This introduces a stack outside of the tree and record the last open-brace on the stack instead of using node.next field. Link: https://lkml.kernel.org/r/160068148267.1088739.8264704338030168660.stgit@devnote2 Fixes: 76db5a2 ("bootconfig: Add Extra Boot Config support") Cc: Ingo Molnar <mingo@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
1 parent a27026e commit ead1e19

1 file changed

Lines changed: 23 additions & 13 deletions

File tree

lib/bootconfig.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ static size_t xbc_data_size __initdata;
3131
static struct xbc_node *last_parent __initdata;
3232
static const char *xbc_err_msg __initdata;
3333
static int xbc_err_pos __initdata;
34+
static int open_brace[XBC_DEPTH_MAX] __initdata;
35+
static int brace_index __initdata;
3436

3537
static int __init xbc_parse_error(const char *msg, const char *p)
3638
{
@@ -431,27 +433,27 @@ static char *skip_spaces_until_newline(char *p)
431433
return p;
432434
}
433435

434-
static int __init __xbc_open_brace(void)
436+
static int __init __xbc_open_brace(char *p)
435437
{
436-
/* Mark the last key as open brace */
437-
last_parent->next = XBC_NODE_MAX;
438+
/* Push the last key as open brace */
439+
open_brace[brace_index++] = xbc_node_index(last_parent);
440+
if (brace_index >= XBC_DEPTH_MAX)
441+
return xbc_parse_error("Exceed max depth of braces", p);
438442

439443
return 0;
440444
}
441445

442446
static int __init __xbc_close_brace(char *p)
443447
{
444-
struct xbc_node *node;
445-
446-
if (!last_parent || last_parent->next != XBC_NODE_MAX)
448+
brace_index--;
449+
if (!last_parent || brace_index < 0 ||
450+
(open_brace[brace_index] != xbc_node_index(last_parent)))
447451
return xbc_parse_error("Unexpected closing brace", p);
448452

449-
node = last_parent;
450-
node->next = 0;
451-
do {
452-
node = xbc_node_get_parent(node);
453-
} while (node && node->next != XBC_NODE_MAX);
454-
last_parent = node;
453+
if (brace_index == 0)
454+
last_parent = NULL;
455+
else
456+
last_parent = &xbc_nodes[open_brace[brace_index - 1]];
455457

456458
return 0;
457459
}
@@ -661,7 +663,7 @@ static int __init xbc_open_brace(char **k, char *n)
661663
return ret;
662664
*k = n;
663665

664-
return __xbc_open_brace();
666+
return __xbc_open_brace(n - 1);
665667
}
666668

667669
static int __init xbc_close_brace(char **k, char *n)
@@ -681,6 +683,13 @@ static int __init xbc_verify_tree(void)
681683
int i, depth, len, wlen;
682684
struct xbc_node *n, *m;
683685

686+
/* Brace closing */
687+
if (brace_index) {
688+
n = &xbc_nodes[open_brace[brace_index]];
689+
return xbc_parse_error("Brace is not closed",
690+
xbc_node_get_data(n));
691+
}
692+
684693
/* Empty tree */
685694
if (xbc_node_num == 0) {
686695
xbc_parse_error("Empty config", xbc_data);
@@ -745,6 +754,7 @@ void __init xbc_destroy_all(void)
745754
xbc_node_num = 0;
746755
memblock_free(__pa(xbc_nodes), sizeof(struct xbc_node) * XBC_NODE_MAX);
747756
xbc_nodes = NULL;
757+
brace_index = 0;
748758
}
749759

750760
/**

0 commit comments

Comments
 (0)