aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2013-11-02 03:11:02 -0400
committerShawn Guo <shawn.guo@freescale.com>2014-05-16 04:19:13 -0400
commit9fc0a1b9cac31f348d4d64b2329b3d3e2aaf1cc9 (patch)
tree217b06f6aeafe4b472ebe83aef71f7e9bf1325b9
parent9c67477d3750f413e59e04c91abfbcd6076930a9 (diff)
ENGR00313685-11 of/irq: Fix potential buffer overflow
commit 355e62f5ad12b005c862838156262eb2df2f8dff upstream. Commit 2361613206e6, "of/irq: Refactor interrupt-map parsing" introduced a potential buffer overflow bug because it doesn't do sufficient range checking on the input data. This patch adds the appropriate checking and buffer size adjustments. If the bounds are out of range then warn loudly. MAX_PHANDLE_ARGS should be sufficient. If it is not then the value can be increased. Signed-off-by: Grant Likely <grant.likely@linaro.org> Cc: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
-rw-r--r--drivers/of/irq.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 964b596d343b..659c14269872 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -95,9 +95,9 @@ struct device_node *of_irq_find_parent(struct device_node *child)
95int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) 95int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
96{ 96{
97 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; 97 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
98 __be32 initial_match_array[8]; 98 __be32 initial_match_array[MAX_PHANDLE_ARGS];
99 const __be32 *match_array = initial_match_array; 99 const __be32 *match_array = initial_match_array;
100 const __be32 *tmp, *imap, *imask, dummy_imask[] = { ~0, ~0, ~0, ~0, ~0 }; 100 const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 };
101 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; 101 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
102 int imaplen, match, i; 102 int imaplen, match, i;
103 103
@@ -147,6 +147,10 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
147 147
148 pr_debug(" -> addrsize=%d\n", addrsize); 148 pr_debug(" -> addrsize=%d\n", addrsize);
149 149
150 /* Range check so that the temporary buffer doesn't overflow */
151 if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS))
152 goto fail;
153
150 /* Precalculate the match array - this simplifies match loop */ 154 /* Precalculate the match array - this simplifies match loop */
151 for (i = 0; i < addrsize; i++) 155 for (i = 0; i < addrsize; i++)
152 initial_match_array[i] = addr ? addr[i] : 0; 156 initial_match_array[i] = addr ? addr[i] : 0;
@@ -229,6 +233,8 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
229 newintsize, newaddrsize); 233 newintsize, newaddrsize);
230 234
231 /* Check for malformed properties */ 235 /* Check for malformed properties */
236 if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS))
237 goto fail;
232 if (imaplen < (newaddrsize + newintsize)) 238 if (imaplen < (newaddrsize + newintsize))
233 goto fail; 239 goto fail;
234 240