Unverified Commit e9b2abc0 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11939 of/irq: Prevent device address out-of-bounds read in interrupt map walk

parents 75e15783 f0549cc0
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -288,7 +288,8 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
	struct device_node *p;
	const __be32 *addr;
	u32 intsize;
	int i, res;
	int i, res, addr_len;
	__be32 addr_buf[3] = { 0 };

	pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index);

@@ -297,13 +298,19 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
		return of_irq_parse_oldworld(device, index, out_irq);

	/* Get the reg property (if any) */
	addr = of_get_property(device, "reg", NULL);
	addr = of_get_property(device, "reg", &addr_len);

	/* Prevent out-of-bounds read in case of longer interrupt parent address size */
	if (addr_len > (3 * sizeof(__be32)))
		addr_len = 3 * sizeof(__be32);
	if (addr)
		memcpy(addr_buf, addr, addr_len);

	/* Try the new-style interrupts-extended first */
	res = of_parse_phandle_with_args(device, "interrupts-extended",
					"#interrupt-cells", index, out_irq);
	if (!res)
		return of_irq_parse_raw(addr, out_irq);
		return of_irq_parse_raw(addr_buf, out_irq);

	/* Look for the interrupt parent. */
	p = of_irq_find_parent(device);
@@ -333,7 +340,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar


	/* Check if there are any interrupt-map translations to process */
	res = of_irq_parse_raw(addr, out_irq);
	res = of_irq_parse_raw(addr_buf, out_irq);
 out:
	of_node_put(p);
	return res;