Commit bdac5c2b authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Steven Rostedt (VMware)

bootconfig: Allocate xbc_data inside xbc_init()

Allocate 'xbc_data' in the xbc_init() so that it does
not need to care about the ownership of the copied
data.

Link: https://lkml.kernel.org/r/163177339986.682366.898762699429769117.stgit@devnote2Suggested-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Signed-off-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 6644c654
...@@ -271,7 +271,7 @@ static inline int __init xbc_node_compose_key(struct xbc_node *node, ...@@ -271,7 +271,7 @@ static inline int __init xbc_node_compose_key(struct xbc_node *node,
} }
/* XBC node initializer */ /* XBC node initializer */
int __init xbc_init(char *buf, const char **emsg, int *epos); int __init xbc_init(const char *buf, size_t size, const char **emsg, int *epos);
/* XBC cleanup data structures */ /* XBC cleanup data structures */
......
...@@ -409,7 +409,7 @@ static void __init setup_boot_config(void) ...@@ -409,7 +409,7 @@ static void __init setup_boot_config(void)
const char *msg; const char *msg;
int pos; int pos;
u32 size, csum; u32 size, csum;
char *data, *copy, *err; char *data, *err;
int ret; int ret;
/* Cut out the bootconfig data even if we have no bootconfig option */ /* Cut out the bootconfig data even if we have no bootconfig option */
...@@ -442,16 +442,7 @@ static void __init setup_boot_config(void) ...@@ -442,16 +442,7 @@ static void __init setup_boot_config(void)
return; return;
} }
copy = memblock_alloc(size + 1, SMP_CACHE_BYTES); ret = xbc_init(data, size, &msg, &pos);
if (!copy) {
pr_err("Failed to allocate memory for bootconfig\n");
return;
}
memcpy(copy, data, size);
copy[size] = '\0';
ret = xbc_init(copy, &msg, &pos);
if (ret < 0) { if (ret < 0) {
if (pos < 0) if (pos < 0)
pr_err("Failed to init bootconfig: %s.\n", msg); pr_err("Failed to init bootconfig: %s.\n", msg);
......
...@@ -789,6 +789,7 @@ static int __init xbc_verify_tree(void) ...@@ -789,6 +789,7 @@ static int __init xbc_verify_tree(void)
*/ */
void __init xbc_destroy_all(void) void __init xbc_destroy_all(void)
{ {
memblock_free_ptr(xbc_data, xbc_data_size);
xbc_data = NULL; xbc_data = NULL;
xbc_data_size = 0; xbc_data_size = 0;
xbc_node_num = 0; xbc_node_num = 0;
...@@ -799,19 +800,20 @@ void __init xbc_destroy_all(void) ...@@ -799,19 +800,20 @@ void __init xbc_destroy_all(void)
/** /**
* xbc_init() - Parse given XBC file and build XBC internal tree * xbc_init() - Parse given XBC file and build XBC internal tree
* @buf: boot config text * @data: The boot config text original data
* @size: The size of @data
* @emsg: A pointer of const char * to store the error message * @emsg: A pointer of const char * to store the error message
* @epos: A pointer of int to store the error position * @epos: A pointer of int to store the error position
* *
* This parses the boot config text in @buf. @buf must be a * This parses the boot config text in @data. @size must be smaller
* null terminated string and smaller than XBC_DATA_MAX. * than XBC_DATA_MAX.
* Return the number of stored nodes (>0) if succeeded, or -errno * Return the number of stored nodes (>0) if succeeded, or -errno
* if there is any error. * if there is any error.
* In error cases, @emsg will be updated with an error message and * In error cases, @emsg will be updated with an error message and
* @epos will be updated with the error position which is the byte offset * @epos will be updated with the error position which is the byte offset
* of @buf. If the error is not a parser error, @epos will be -1. * of @buf. If the error is not a parser error, @epos will be -1.
*/ */
int __init xbc_init(char *buf, const char **emsg, int *epos) int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos)
{ {
char *p, *q; char *p, *q;
int ret, c; int ret, c;
...@@ -824,28 +826,35 @@ int __init xbc_init(char *buf, const char **emsg, int *epos) ...@@ -824,28 +826,35 @@ int __init xbc_init(char *buf, const char **emsg, int *epos)
*emsg = "Bootconfig is already initialized"; *emsg = "Bootconfig is already initialized";
return -EBUSY; return -EBUSY;
} }
if (size > XBC_DATA_MAX || size == 0) {
ret = strlen(buf);
if (ret > XBC_DATA_MAX - 1 || ret == 0) {
if (emsg) if (emsg)
*emsg = ret ? "Config data is too big" : *emsg = size ? "Config data is too big" :
"Config data is empty"; "Config data is empty";
return -ERANGE; return -ERANGE;
} }
xbc_data = memblock_alloc(size + 1, SMP_CACHE_BYTES);
if (!xbc_data) {
if (emsg)
*emsg = "Failed to allocate bootconfig data";
return -ENOMEM;
}
memcpy(xbc_data, data, size);
xbc_data[size] = '\0';
xbc_data_size = size + 1;
xbc_nodes = memblock_alloc(sizeof(struct xbc_node) * XBC_NODE_MAX, xbc_nodes = memblock_alloc(sizeof(struct xbc_node) * XBC_NODE_MAX,
SMP_CACHE_BYTES); SMP_CACHE_BYTES);
if (!xbc_nodes) { if (!xbc_nodes) {
if (emsg) if (emsg)
*emsg = "Failed to allocate bootconfig nodes"; *emsg = "Failed to allocate bootconfig nodes";
xbc_destroy_all();
return -ENOMEM; return -ENOMEM;
} }
memset(xbc_nodes, 0, sizeof(struct xbc_node) * XBC_NODE_MAX); memset(xbc_nodes, 0, sizeof(struct xbc_node) * XBC_NODE_MAX);
xbc_data = buf;
xbc_data_size = ret + 1;
last_parent = NULL;
p = buf; last_parent = NULL;
p = xbc_data;
do { do {
q = strpbrk(p, "{}=+;:\n#"); q = strpbrk(p, "{}=+;:\n#");
if (!q) { if (!q) {
......
...@@ -229,7 +229,7 @@ static int load_xbc_from_initrd(int fd, char **buf) ...@@ -229,7 +229,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
return -EINVAL; return -EINVAL;
} }
ret = xbc_init(*buf, &msg, NULL); ret = xbc_init(*buf, size, &msg, NULL);
/* Wrong data */ /* Wrong data */
if (ret < 0) { if (ret < 0) {
pr_err("parse error: %s.\n", msg); pr_err("parse error: %s.\n", msg);
...@@ -269,7 +269,7 @@ static int init_xbc_with_error(char *buf, int len) ...@@ -269,7 +269,7 @@ static int init_xbc_with_error(char *buf, int len)
if (!copy) if (!copy)
return -ENOMEM; return -ENOMEM;
ret = xbc_init(buf, &msg, &pos); ret = xbc_init(buf, len, &msg, &pos);
if (ret < 0) if (ret < 0)
show_xbc_error(copy, msg, pos); show_xbc_error(copy, msg, pos);
free(copy); free(copy);
...@@ -382,7 +382,7 @@ static int apply_xbc(const char *path, const char *xbc_path) ...@@ -382,7 +382,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
memcpy(data, buf, size); memcpy(data, buf, size);
/* Check the data format */ /* Check the data format */
ret = xbc_init(buf, &msg, &pos); ret = xbc_init(buf, size, &msg, &pos);
if (ret < 0) { if (ret < 0) {
show_xbc_error(data, msg, pos); show_xbc_error(data, msg, pos);
free(data); free(data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment