diff options
author | Sona Sarmadi <sona.sarmadi@enea.com> | 2016-04-14 14:46:07 +0200 |
---|---|---|
committer | Tudor Florea <tudor.florea@enea.com> | 2016-04-15 21:55:10 +0200 |
commit | 1b7f083c0f10c48754c07c49e207746f54ac402e (patch) | |
tree | c9ab13ed0e8c3fa7f8c656ad56a93af8a2fe7275 | |
parent | 735bb1170100e71eed6c54a8c2c87942df01f864 (diff) | |
download | meta-enea-1b7f083c0f10c48754c07c49e207746f54ac402e.tar.gz |
kernel-ipv4: CVE-2016-3156
Fixes denial of service when destroying a network interface
(in the linux qoriq-3.12).
Reference:
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-3156
Reference to the upstream patch:
https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/
patch/?id=5cc4ff312ac06ee4c49801f5b288c1118c3e5785
Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
-rw-r--r-- | recipes-kernel/linux/linux-qoriq-3.12/ipv4-CVE-2016-3156.patch | 135 | ||||
-rw-r--r-- | recipes-kernel/linux/linux-qoriq-common.inc | 1 |
2 files changed, 136 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-qoriq-3.12/ipv4-CVE-2016-3156.patch b/recipes-kernel/linux/linux-qoriq-3.12/ipv4-CVE-2016-3156.patch new file mode 100644 index 0000000..711d324 --- /dev/null +++ b/recipes-kernel/linux/linux-qoriq-3.12/ipv4-CVE-2016-3156.patch | |||
@@ -0,0 +1,135 @@ | |||
1 | From 5cc4ff312ac06ee4c49801f5b288c1118c3e5785 Mon Sep 17 00:00:00 2001 | ||
2 | From: "David S. Miller" <davem@davemloft.net> | ||
3 | Date: Sun, 13 Mar 2016 23:28:00 -0400 | ||
4 | Subject: ipv4: Don't do expensive useless work during inetdev destroy. | ||
5 | |||
6 | commit fbd40ea0180a2d328c5adc61414dc8bab9335ce2 upstream. | ||
7 | |||
8 | When an inetdev is destroyed, every address assigned to the interface | ||
9 | is removed. And in this scenerio we do two pointless things which can | ||
10 | be very expensive if the number of assigned interfaces is large: | ||
11 | |||
12 | 1) Address promotion. We are deleting all addresses, so there is no | ||
13 | point in doing this. | ||
14 | |||
15 | 2) A full nf conntrack table purge for every address. We only need to | ||
16 | do this once, as is already caught by the existing | ||
17 | masq_dev_notifier so masq_inet_event() can skip this. | ||
18 | |||
19 | [mk] 3.12.*: The change in masq_inet_event() needs to be duplicated in | ||
20 | both IPv4 and IPv6 version of the function, these two were merged in | ||
21 | 3.18. | ||
22 | |||
23 | CVE: CVE-2016-3156 | ||
24 | Upstream-Status: Backport | ||
25 | |||
26 | Reported-by: Solar Designer <solar@openwall.com> | ||
27 | Signed-off-by: David S. Miller <davem@davemloft.net> | ||
28 | Tested-by: Cyrill Gorcunov <gorcunov@openvz.org> | ||
29 | Acked-by: Michal Kubecek <mkubecek@suse.cz> | ||
30 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
31 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
32 | --- | ||
33 | net/ipv4/devinet.c | 4 ++++ | ||
34 | net/ipv4/fib_frontend.c | 4 ++++ | ||
35 | net/ipv4/netfilter/ipt_MASQUERADE.c | 12 ++++++++++-- | ||
36 | net/ipv6/netfilter/ip6t_MASQUERADE.c | 12 ++++++++++-- | ||
37 | 4 files changed, 28 insertions(+), 4 deletions(-) | ||
38 | |||
39 | diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c | ||
40 | index 6844710..6678beb 100644 | ||
41 | --- a/net/ipv4/devinet.c | ||
42 | +++ b/net/ipv4/devinet.c | ||
43 | @@ -328,6 +328,9 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | ||
44 | |||
45 | ASSERT_RTNL(); | ||
46 | |||
47 | + if (in_dev->dead) | ||
48 | + goto no_promotions; | ||
49 | + | ||
50 | /* 1. Deleting primary ifaddr forces deletion all secondaries | ||
51 | * unless alias promotion is set | ||
52 | **/ | ||
53 | @@ -374,6 +377,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | ||
54 | fib_del_ifaddr(ifa, ifa1); | ||
55 | } | ||
56 | |||
57 | +no_promotions: | ||
58 | /* 2. Unlink it */ | ||
59 | |||
60 | *ifap = ifa1->ifa_next; | ||
61 | diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c | ||
62 | index f7f8cff..25a0946 100644 | ||
63 | --- a/net/ipv4/fib_frontend.c | ||
64 | +++ b/net/ipv4/fib_frontend.c | ||
65 | @@ -812,6 +812,9 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim) | ||
66 | subnet = 1; | ||
67 | } | ||
68 | |||
69 | + if (in_dev->dead) | ||
70 | + goto no_promotions; | ||
71 | + | ||
72 | /* Deletion is more complicated than add. | ||
73 | * We should take care of not to delete too much :-) | ||
74 | * | ||
75 | @@ -887,6 +890,7 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim) | ||
76 | } | ||
77 | } | ||
78 | |||
79 | +no_promotions: | ||
80 | if (!(ok & BRD_OK)) | ||
81 | fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); | ||
82 | if (subnet && ifa->ifa_prefixlen < 31) { | ||
83 | diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c | ||
84 | index 00352ce..3bc1c98 100644 | ||
85 | --- a/net/ipv4/netfilter/ipt_MASQUERADE.c | ||
86 | +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | ||
87 | @@ -128,10 +128,18 @@ static int masq_inet_event(struct notifier_block *this, | ||
88 | unsigned long event, | ||
89 | void *ptr) | ||
90 | { | ||
91 | - struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev; | ||
92 | + struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev; | ||
93 | struct netdev_notifier_info info; | ||
94 | |||
95 | - netdev_notifier_info_init(&info, dev); | ||
96 | + /* The masq_dev_notifier will catch the case of the device going | ||
97 | + * down. So if the inetdev is dead and being destroyed we have | ||
98 | + * no work to do. Otherwise this is an individual address removal | ||
99 | + * and we have to perform the flush. | ||
100 | + */ | ||
101 | + if (idev->dead) | ||
102 | + return NOTIFY_DONE; | ||
103 | + | ||
104 | + netdev_notifier_info_init(&info, idev->dev); | ||
105 | return masq_device_event(this, event, &info); | ||
106 | } | ||
107 | |||
108 | diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c | ||
109 | index 3e4e92d..bee09e9 100644 | ||
110 | --- a/net/ipv6/netfilter/ip6t_MASQUERADE.c | ||
111 | +++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c | ||
112 | @@ -88,10 +88,18 @@ static struct notifier_block masq_dev_notifier = { | ||
113 | static int masq_inet_event(struct notifier_block *this, | ||
114 | unsigned long event, void *ptr) | ||
115 | { | ||
116 | - struct inet6_ifaddr *ifa = ptr; | ||
117 | + struct inet6_dev *idev = ((struct inet6_ifaddr *)ptr)->idev; | ||
118 | struct netdev_notifier_info info; | ||
119 | |||
120 | - netdev_notifier_info_init(&info, ifa->idev->dev); | ||
121 | + /* The masq_dev_notifier will catch the case of the device going | ||
122 | + * down. So if the inetdev is dead and being destroyed we have | ||
123 | + * no work to do. Otherwise this is an individual address removal | ||
124 | + * and we have to perform the flush. | ||
125 | + */ | ||
126 | + if (idev->dead) | ||
127 | + return NOTIFY_DONE; | ||
128 | + | ||
129 | + netdev_notifier_info_init(&info, idev->dev); | ||
130 | return masq_device_event(this, event, &info); | ||
131 | } | ||
132 | |||
133 | -- | ||
134 | cgit v0.12 | ||
135 | |||
diff --git a/recipes-kernel/linux/linux-qoriq-common.inc b/recipes-kernel/linux/linux-qoriq-common.inc index 44b4ff5..53b7bfc 100644 --- a/recipes-kernel/linux/linux-qoriq-common.inc +++ b/recipes-kernel/linux/linux-qoriq-common.inc | |||
@@ -28,6 +28,7 @@ SRC_URI += "file://b4860-hard_irq_disable-bug.patch \ | |||
28 | file://net-unix-CVE-2013-7446.patch \ | 28 | file://net-unix-CVE-2013-7446.patch \ |
29 | file://ALSA-CVE-2016-2546.patch \ | 29 | file://ALSA-CVE-2016-2546.patch \ |
30 | file://ALSA-CVE-2016-2384.patch \ | 30 | file://ALSA-CVE-2016-2384.patch \ |
31 | file://ipv4-CVE-2016-3156.patch \ | ||
31 | " | 32 | " |
32 | 33 | ||
33 | SRC_URI += "file://cfg/00013-localversion.cfg \ | 34 | SRC_URI += "file://cfg/00013-localversion.cfg \ |