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

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@devnote2



Suggested-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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ static inline int __init xbc_node_compose_key(struct xbc_node *node,
}

/* 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 */
+2 −11
Original line number Diff line number Diff line
@@ -409,7 +409,7 @@ static void __init setup_boot_config(void)
	const char *msg;
	int pos;
	u32 size, csum;
	char *data, *copy, *err;
	char *data, *err;
	int ret;

	/* Cut out the bootconfig data even if we have no bootconfig option */
@@ -442,16 +442,7 @@ static void __init setup_boot_config(void)
		return;
	}

	copy = memblock_alloc(size + 1, SMP_CACHE_BYTES);
	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);
	ret = xbc_init(data, size, &msg, &pos);
	if (ret < 0) {
		if (pos < 0)
			pr_err("Failed to init bootconfig: %s.\n", msg);
+21 −12
Original line number Diff line number Diff line
@@ -789,6 +789,7 @@ static int __init xbc_verify_tree(void)
 */
void __init xbc_destroy_all(void)
{
	memblock_free_ptr(xbc_data, xbc_data_size);
	xbc_data = NULL;
	xbc_data_size = 0;
	xbc_node_num = 0;
@@ -799,19 +800,20 @@ void __init xbc_destroy_all(void)

/**
 * 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
 * @epos: A pointer of int to store the error position
 *
 * This parses the boot config text in @buf. @buf must be a
 * null terminated string and smaller than XBC_DATA_MAX.
 * This parses the boot config text in @data. @size must be smaller
 * than XBC_DATA_MAX.
 * Return the number of stored nodes (>0) if succeeded, or -errno
 * if there is any error.
 * 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
 * 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;
	int ret, c;
@@ -824,28 +826,35 @@ int __init xbc_init(char *buf, const char **emsg, int *epos)
			*emsg = "Bootconfig is already initialized";
		return -EBUSY;
	}

	ret = strlen(buf);
	if (ret > XBC_DATA_MAX - 1 || ret == 0) {
	if (size > XBC_DATA_MAX || size == 0) {
		if (emsg)
			*emsg = ret ? "Config data is too big" :
			*emsg = size ? "Config data is too big" :
				"Config data is empty";
		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,
				   SMP_CACHE_BYTES);
	if (!xbc_nodes) {
		if (emsg)
			*emsg = "Failed to allocate bootconfig nodes";
		xbc_destroy_all();
		return -ENOMEM;
	}
	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 {
		q = strpbrk(p, "{}=+;:\n#");
		if (!q) {
+3 −3
Original line number Diff line number Diff line
@@ -229,7 +229,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
		return -EINVAL;
	}

	ret = xbc_init(*buf, &msg, NULL);
	ret = xbc_init(*buf, size, &msg, NULL);
	/* Wrong data */
	if (ret < 0) {
		pr_err("parse error: %s.\n", msg);
@@ -269,7 +269,7 @@ static int init_xbc_with_error(char *buf, int len)
	if (!copy)
		return -ENOMEM;

	ret = xbc_init(buf, &msg, &pos);
	ret = xbc_init(buf, len, &msg, &pos);
	if (ret < 0)
		show_xbc_error(copy, msg, pos);
	free(copy);
@@ -382,7 +382,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
	memcpy(data, buf, size);

	/* Check the data format */
	ret = xbc_init(buf, &msg, &pos);
	ret = xbc_init(buf, size, &msg, &pos);
	if (ret < 0) {
		show_xbc_error(data, msg, pos);
		free(data);