aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2013-11-02 03:11:02 -0400
committerGrant Likely <grant.likely@linaro.org>2013-11-03 18:16:43 -0500
commit355e62f5ad12b005c862838156262eb2df2f8dff (patch)
tree21263268a1e0a9e07680c027f406d42e4d85e268 /drivers/of
parent78119fd1068cc068f6112a57a5f6de0e5b20245a (diff)
of/irq: Fix potential buffer overflow
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>
Diffstat (limited to 'drivers/of')
-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 52dba6a01423..d385bb824772 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