mvebu: backport mainline patches from kernel 3.13
[openwrt.git] / target / linux / mvebu / patches-3.10 / 0191-of-irq-Fix-potential-buffer-overflow.patch
1 From 5a1bd82f089e19ba049a871a0d5538ed9eb5e5cd Mon Sep 17 00:00:00 2001
2 From: Grant Likely <grant.likely@linaro.org>
3 Date: Thu, 19 Dec 2013 09:31:02 -0300
4 Subject: [PATCH 191/203] of/irq: Fix potential buffer overflow
5
6 Commit 2361613206e6, "of/irq: Refactor interrupt-map parsing" introduced
7 a potential buffer overflow bug because it doesn't do sufficient range
8 checking on the input data. This patch adds the appropriate checking and
9 buffer size adjustments. If the bounds are out of range then warn
10 loudly. MAX_PHANDLE_ARGS should be sufficient. If it is not then the
11 value can be increased.
12
13 Signed-off-by: Grant Likely <grant.likely@linaro.org>
14 Cc: Rob Herring <rob.herring@calxeda.com>
15 ---
16  drivers/of/irq.c | 10 ++++++++--
17  1 file changed, 8 insertions(+), 2 deletions(-)
18
19 --- a/drivers/of/irq.c
20 +++ b/drivers/of/irq.c
21 @@ -95,9 +95,9 @@ struct device_node *of_irq_find_parent(s
22  int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
23  {
24         struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
25 -       __be32 initial_match_array[8];
26 +       __be32 initial_match_array[MAX_PHANDLE_ARGS];
27         const __be32 *match_array = initial_match_array;
28 -       const __be32 *tmp, *imap, *imask, dummy_imask[] = { ~0, ~0, ~0, ~0, ~0 };
29 +       const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 };
30         u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
31         int imaplen, match, i;
32  
33 @@ -147,6 +147,10 @@ int of_irq_parse_raw(const __be32 *addr,
34  
35         pr_debug(" -> addrsize=%d\n", addrsize);
36  
37 +       /* Range check so that the temporary buffer doesn't overflow */
38 +       if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS))
39 +               goto fail;
40 +
41         /* Precalculate the match array - this simplifies match loop */
42         for (i = 0; i < addrsize; i++)
43                 initial_match_array[i] = addr ? addr[i] : 0;
44 @@ -229,6 +233,8 @@ int of_irq_parse_raw(const __be32 *addr,
45                             newintsize, newaddrsize);
46  
47                         /* Check for malformed properties */
48 +                       if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS))
49 +                               goto fail;
50                         if (imaplen < (newaddrsize + newintsize))
51                                 goto fail;
52