aboutsummaryrefslogtreecommitdiffstats
path: root/main/linux-virt-grsec
diff options
context:
space:
mode:
authorLeonardo Arena <rnalrd@alpinelinux.org>2013-06-11 09:48:45 +0000
committerLeonardo Arena <rnalrd@alpinelinux.org>2013-06-11 09:48:59 +0000
commitf3dd5095137cc77d9c634e5bb670b6f024d499ad (patch)
treefb32417505a0420cf7120a337181d5c4e5523b3c /main/linux-virt-grsec
parent47bb9d7aa2cac0320a6bbe5d052af53c3d57a9f1 (diff)
downloadaports-f3dd5095137cc77d9c634e5bb670b6f024d499ad.tar.bz2
aports-f3dd5095137cc77d9c634e5bb670b6f024d499ad.tar.xz
main/linux-virt-grsec: upgrade to 3.9.5
Diffstat (limited to 'main/linux-virt-grsec')
-rw-r--r--main/linux-virt-grsec/0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch68
-rw-r--r--main/linux-virt-grsec/0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch35
-rw-r--r--main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch201
-rw-r--r--main/linux-virt-grsec/0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch37
-rw-r--r--main/linux-virt-grsec/0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch116
-rw-r--r--main/linux-virt-grsec/0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch (renamed from main/linux-virt-grsec/RFC-net-ipv4-Use-next-hop-exceptions-also-for-input-routes.patch)139
-rw-r--r--main/linux-virt-grsec/APKBUILD77
-rw-r--r--main/linux-virt-grsec/grsecurity-2.9.1-3.9.5-201306102218.patch (renamed from main/linux-virt-grsec/grsecurity-2.9.1-3.9.4-201306011536.patch)799
-rw-r--r--main/linux-virt-grsec/ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch44
-rw-r--r--main/linux-virt-grsec/ipv4-remove-output-route-check-in-ipv4_mtu.patch38
-rw-r--r--main/linux-virt-grsec/kernelconfig.x865
-rw-r--r--main/linux-virt-grsec/kernelconfig.x86_645
-rw-r--r--main/linux-virt-grsec/leds-leds-gpio-reserve-gpio-before-using-it.patch114
-rw-r--r--main/linux-virt-grsec/v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch89
14 files changed, 959 insertions, 808 deletions
diff --git a/main/linux-virt-grsec/0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch b/main/linux-virt-grsec/0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
new file mode 100644
index 0000000000..7357a330f8
--- /dev/null
+++ b/main/linux-virt-grsec/0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
@@ -0,0 +1,68 @@
+From 1225b1090991bdcab819bdab96be329397563f1c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Thu, 23 May 2013 11:30:23 +0300
+Subject: [PATCH 1/6] net: inform NETDEV_CHANGE callbacks which flags were
+ changed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In certain cases (like the follow up commit to arp.c) will need to
+check which flags actually changed to avoid excessive work.
+
+Ben Hutchings nicely worded why to put these transient flags to
+struct net_device for the time being:
+> It's inelegant to put transient data associated with an event in a
+> persistent data structure. On the other hand, having every user cache
+> the old state is pretty awful as well.
+>
+> Really, netdev notifiers should be changed to accept a structure that
+> encapsulates the changes rather than just a pointer to the net_device.
+> But making such a change would be an enormous pain and error-prone
+> because notifier functions aren't type-safe.
+>
+> As an interim solution, I think either the general flags_changed or
+> old_flags would be preferable to defining extra transient flags.
+
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+Acked-by: Ben Hutchings <bhutchings@solarflare.com>
+---
+ include/linux/netdevice.h | 4 +++-
+ net/core/dev.c | 5 ++++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 6151e90..8b3c649 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1112,7 +1112,9 @@ struct net_device {
+ /* Hardware header description */
+ const struct header_ops *header_ops;
+
+- unsigned int flags; /* interface flags (a la BSD) */
++ unsigned int flags; /* interface flags (a la BSD) */
++ unsigned int flags_changed; /* flags that are being changed
++ * valid during NETDEV_CHANGE notifier */
+ unsigned int priv_flags; /* Like 'flags' but invisible to userspace.
+ * See if.h for definitions. */
+ unsigned short gflags;
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 9a278e9..2f3feae 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4683,8 +4683,11 @@ void __dev_notify_flags(struct net_device *dev, unsigned int old_flags)
+ }
+
+ if (dev->flags & IFF_UP &&
+- (changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE)))
++ (changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE))) {
++ dev->flags_changed = changes;
+ call_netdevice_notifiers(NETDEV_CHANGE, dev);
++ dev->flags_changed = 0;
++ }
+ }
+
+ /**
+--
+1.8.2.3
+
diff --git a/main/linux-virt-grsec/0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch b/main/linux-virt-grsec/0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
new file mode 100644
index 0000000000..0e364f4718
--- /dev/null
+++ b/main/linux-virt-grsec/0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
@@ -0,0 +1,35 @@
+From 36fbd62c47d800705d9989c69994359711514165 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Thu, 23 May 2013 11:43:55 +0300
+Subject: [PATCH 2/6] arp: flush arp cache on IFF_NOARP change
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+IFF_NOARP affects what kind of neighbor entries are created
+(nud NOARP or nud INCOMPLETE). If the flag changes, flush the arp
+cache to refresh all entries.
+
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+---
+ net/ipv4/arp.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
+index fea4929..2a06ecf 100644
+--- a/net/ipv4/arp.c
++++ b/net/ipv4/arp.c
+@@ -1226,6 +1226,10 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event,
+ neigh_changeaddr(&arp_tbl, dev);
+ rt_cache_flush(dev_net(dev));
+ break;
++ case NETDEV_CHANGE:
++ if (dev->flags_changed & IFF_NOARP)
++ neigh_changeaddr(&arp_tbl, dev);
++ break;
+ default:
+ break;
+ }
+--
+1.8.2.3
+
diff --git a/main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch b/main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
new file mode 100644
index 0000000000..807dba0b3c
--- /dev/null
+++ b/main/linux-virt-grsec/0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
@@ -0,0 +1,201 @@
+From 777eadba40c19bcfdb48807e7b0547ef30555671 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Sat, 25 May 2013 15:42:30 +0300
+Subject: [PATCH 3/6] ipv4: properly refresh rtable entries on pmtu/redirect
+ events
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This reverts commit 05ab86c5 (xfrm4: Invalidate all ipv4 routes on
+IPsec pmtu events). Flushing all cached entries is not needed.
+
+Instead, invalidate only the related next hop dsts to recheck for
+the added next hop exception where needed. This also fixes a subtle
+race due to bumping generation id's before updating the pmtu.
+
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+---
+ net/ipv4/ah4.c | 7 ++-----
+ net/ipv4/esp4.c | 7 ++-----
+ net/ipv4/ipcomp.c | 7 ++-----
+ net/ipv4/route.c | 63 ++++++++++++++++++++++++++++++++-----------------------
+ 4 files changed, 43 insertions(+), 41 deletions(-)
+
+diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
+index 2e7f194..7179026 100644
+--- a/net/ipv4/ah4.c
++++ b/net/ipv4/ah4.c
+@@ -419,12 +419,9 @@ static void ah4_err(struct sk_buff *skb, u32 info)
+ if (!x)
+ return;
+
+- if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) {
+- atomic_inc_unchecked(&flow_cache_genid);
+- rt_genid_bump(net);
+-
++ if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
+ ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_AH, 0);
+- } else
++ else
+ ipv4_redirect(skb, net, 0, 0, IPPROTO_AH, 0);
+ xfrm_state_put(x);
+ }
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
+index 4cfe34d..ab3d814 100644
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -502,12 +502,9 @@ static void esp4_err(struct sk_buff *skb, u32 info)
+ if (!x)
+ return;
+
+- if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) {
+- atomic_inc_unchecked(&flow_cache_genid);
+- rt_genid_bump(net);
+-
++ if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
+ ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0);
+- } else
++ else
+ ipv4_redirect(skb, net, 0, 0, IPPROTO_ESP, 0);
+ xfrm_state_put(x);
+ }
+diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
+index f01d1b1..48b3f0b 100644
+--- a/net/ipv4/ipcomp.c
++++ b/net/ipv4/ipcomp.c
+@@ -47,12 +47,9 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
+ if (!x)
+ return;
+
+- if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) {
+- atomic_inc_unchecked(&flow_cache_genid);
+- rt_genid_bump(net);
+-
++ if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
+ ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_COMP, 0);
+- } else
++ else
+ ipv4_redirect(skb, net, 0, 0, IPPROTO_COMP, 0);
+ xfrm_state_put(x);
+ }
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 6e28514..8dedfeb 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -594,11 +594,25 @@ static inline u32 fnhe_hashfun(__be32 daddr)
+ return hval & (FNHE_HASH_SIZE - 1);
+ }
+
++static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnhe)
++{
++ rt->rt_pmtu = fnhe->fnhe_pmtu;
++ rt->dst.expires = fnhe->fnhe_expires;
++
++ if (fnhe->fnhe_gw) {
++ rt->rt_flags |= RTCF_REDIRECTED;
++ rt->rt_gateway = fnhe->fnhe_gw;
++ rt->rt_uses_gateway = 1;
++ }
++}
++
+ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
+ u32 pmtu, unsigned long expires)
+ {
+ struct fnhe_hash_bucket *hash;
+ struct fib_nh_exception *fnhe;
++ struct rtable *rt;
++ unsigned int i;
+ int depth;
+ u32 hval = fnhe_hashfun(daddr);
+
+@@ -627,8 +641,12 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
+ fnhe->fnhe_gw = gw;
+ if (pmtu) {
+ fnhe->fnhe_pmtu = pmtu;
+- fnhe->fnhe_expires = expires;
++ fnhe->fnhe_expires = max(1UL, expires);
+ }
++ /* Update all cached dsts too */
++ rt = rcu_dereference(fnhe->fnhe_rth);
++ if (rt)
++ fill_route_from_fnhe(rt, fnhe);
+ } else {
+ if (depth > FNHE_RECLAIM_DEPTH)
+ fnhe = fnhe_oldest(hash);
+@@ -644,6 +662,18 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
+ fnhe->fnhe_gw = gw;
+ fnhe->fnhe_pmtu = pmtu;
+ fnhe->fnhe_expires = expires;
++
++ /* Exception created; mark the cached routes for the nexthop
++ * stale, so anyone caching it rechecks if this exception
++ * applies to them.
++ */
++ for_each_possible_cpu(i) {
++ struct rtable __rcu **prt;
++ prt = per_cpu_ptr(nh->nh_pcpu_rth_output, i);
++ rt = rcu_dereference(*prt);
++ if (rt)
++ rt->dst.obsolete = DST_OBSOLETE_KILL;
++ }
+ }
+
+ fnhe->fnhe_stamp = jiffies;
+@@ -917,13 +947,6 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
+ if (mtu < ip_rt_min_pmtu)
+ mtu = ip_rt_min_pmtu;
+
+- if (!rt->rt_pmtu) {
+- dst->obsolete = DST_OBSOLETE_KILL;
+- } else {
+- rt->rt_pmtu = mtu;
+- dst->expires = max(1UL, jiffies + ip_rt_mtu_expires);
+- }
+-
+ rcu_read_lock();
+ if (fib_lookup(dev_net(dst->dev), fl4, &res) == 0) {
+ struct fib_nh *nh = &FIB_RES_NH(res);
+@@ -1063,11 +1086,11 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
+ * DST_OBSOLETE_FORCE_CHK which forces validation calls down
+ * into this function always.
+ *
+- * When a PMTU/redirect information update invalidates a
+- * route, this is indicated by setting obsolete to
+- * DST_OBSOLETE_KILL.
++ * When a PMTU/redirect information update invalidates a route,
++ * this is indicated by setting obsolete to DST_OBSOLETE_KILL or
++ * DST_OBSOLETE_DEAD by dst_free().
+ */
+- if (dst->obsolete == DST_OBSOLETE_KILL || rt_is_expired(rt))
++ if (dst->obsolete != DST_OBSOLETE_FORCE_CHK || rt_is_expired(rt))
+ return NULL;
+ return dst;
+ }
+@@ -1215,20 +1238,8 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
+ fnhe->fnhe_pmtu = 0;
+ fnhe->fnhe_expires = 0;
+ }
+- if (fnhe->fnhe_pmtu) {
+- unsigned long expires = fnhe->fnhe_expires;
+- unsigned long diff = expires - jiffies;
+-
+- if (time_before(jiffies, expires)) {
+- rt->rt_pmtu = fnhe->fnhe_pmtu;
+- dst_set_expires(&rt->dst, diff);
+- }
+- }
+- if (fnhe->fnhe_gw) {
+- rt->rt_flags |= RTCF_REDIRECTED;
+- rt->rt_gateway = fnhe->fnhe_gw;
+- rt->rt_uses_gateway = 1;
+- } else if (!rt->rt_gateway)
++ fill_route_from_fnhe(rt, fnhe);
++ if (!rt->rt_gateway)
+ rt->rt_gateway = daddr;
+
+ rcu_assign_pointer(fnhe->fnhe_rth, rt);
+--
+1.8.2.3
+
diff --git a/main/linux-virt-grsec/0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch b/main/linux-virt-grsec/0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
new file mode 100644
index 0000000000..9b2ad89132
--- /dev/null
+++ b/main/linux-virt-grsec/0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
@@ -0,0 +1,37 @@
+From 90f586dba1465a73295d752abe2451e924ba1888 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Mon, 27 May 2013 08:33:10 +0300
+Subject: [PATCH 4/6] ipv4: rate limit updating of next hop exceptions with
+ same pmtu
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The tunnel devices call update_pmtu for each packet sent, this causes
+contention on the fnhe_lock. Ignore the pmtu update if pmtu is not
+actually changed, and there is still plenty of time before the entry
+expires.
+
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+---
+ net/ipv4/route.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 8dedfeb..85b9c07 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -947,6 +947,10 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
+ if (mtu < ip_rt_min_pmtu)
+ mtu = ip_rt_min_pmtu;
+
++ if (rt->rt_pmtu == mtu &&
++ time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2))
++ return;
++
+ rcu_read_lock();
+ if (fib_lookup(dev_net(dst->dev), fl4, &res) == 0) {
+ struct fib_nh *nh = &FIB_RES_NH(res);
+--
+1.8.2.3
+
diff --git a/main/linux-virt-grsec/0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch b/main/linux-virt-grsec/0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
new file mode 100644
index 0000000000..40cd4fc6c1
--- /dev/null
+++ b/main/linux-virt-grsec/0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
@@ -0,0 +1,116 @@
+From 4a7dbb238480fac2b1ad02a74240efcf225c1f45 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Mon, 27 May 2013 10:55:52 +0300
+Subject: [PATCH 5/6] ipv4: use separate genid for next hop exceptions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+commit 13d82bf5 (ipv4: Fix flushing of cached routing informations)
+added the support to flush learned pmtu information.
+
+However, using rt_genid is quite heavy as it is bumped on route
+add/change and multicast events amongst other places. These can
+happen quote often, especially if using dynamic routing protocols.
+
+While this is ok with routes (as they are just recreated locally),
+the pmtu information is learned from remote systems and the icmp
+notification can come with long delays. It is worthy to have separate
+genid to avoid excessive pmtu resets.
+
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+---
+ include/net/ip_fib.h | 1 +
+ include/net/net_namespace.h | 11 +++++++++++
+ net/ipv4/route.c | 12 ++++++++++--
+ 3 files changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
+index e49db91..44424e9 100644
+--- a/include/net/ip_fib.h
++++ b/include/net/ip_fib.h
+@@ -51,6 +51,7 @@ struct rtable;
+
+ struct fib_nh_exception {
+ struct fib_nh_exception __rcu *fnhe_next;
++ int fnhe_genid;
+ __be32 fnhe_daddr;
+ u32 fnhe_pmtu;
+ __be32 fnhe_gw;
+diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
+index de644bc..b5a5baf 100644
+--- a/include/net/net_namespace.h
++++ b/include/net/net_namespace.h
+@@ -116,6 +116,7 @@ struct net {
+ struct netns_ipvs *ipvs;
+ struct sock *diag_nlsk;
+ atomic_unchecked_t rt_genid;
++ atomic_unchecked_t fnhe_genid;
+ };
+
+ /*
+@@ -338,4 +339,14 @@ static inline void rt_genid_bump(struct net *net)
+ atomic_inc_unchecked(&net->rt_genid);
+ }
+
++static inline int fnhe_genid(struct net *net)
++{
++ return atomic_read_unchecked(&net->fnhe_genid);
++}
++
++static inline void fnhe_genid_bump(struct net *net)
++{
++ atomic_inc_unchecked(&net->fnhe_genid);
++}
++
+ #endif /* __NET_NET_NAMESPACE_H */
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 85b9c07..f44a4bb 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -658,6 +658,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
+ fnhe->fnhe_next = hash->chain;
+ rcu_assign_pointer(hash->chain, fnhe);
+ }
++ fnhe->fnhe_genid = fnhe_genid(dev_net(nh->nh_dev));
+ fnhe->fnhe_daddr = daddr;
+ fnhe->fnhe_gw = gw;
+ fnhe->fnhe_pmtu = pmtu;
+@@ -1236,8 +1237,11 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
+ spin_lock_bh(&fnhe_lock);
+
+ if (daddr == fnhe->fnhe_daddr) {
++ int genid = fnhe_genid(dev_net(rt->dst.dev));
+ struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
+- if (orig && rt_is_expired(orig)) {
++
++ if (fnhe->fnhe_genid != genid) {
++ fnhe->fnhe_genid = genid;
+ fnhe->fnhe_gw = 0;
+ fnhe->fnhe_pmtu = 0;
+ fnhe->fnhe_expires = 0;
+@@ -2443,8 +2447,11 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+ {
++ struct net *net = (struct net *)__ctl->extra1;
++
+ if (write) {
+- rt_cache_flush((struct net *)__ctl->extra1);
++ rt_cache_flush(net);
++ fnhe_genid_bump(net);
+ return 0;
+ }
+
+@@ -2619,6 +2626,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
+ static __net_init int rt_genid_init(struct net *net)
+ {
+ atomic_set_unchecked(&net->rt_genid, 0);
++ atomic_set_unchecked(&net->fnhe_genid, 0);
+ get_random_bytes(&net->ipv4.dev_addr_genid,
+ sizeof(net->ipv4.dev_addr_genid));
+ return 0;
+--
+1.8.2.3
+
diff --git a/main/linux-virt-grsec/RFC-net-ipv4-Use-next-hop-exceptions-also-for-input-routes.patch b/main/linux-virt-grsec/0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
index 2310927e81..9b78e76b2c 100644
--- a/main/linux-virt-grsec/RFC-net-ipv4-Use-next-hop-exceptions-also-for-input-routes.patch
+++ b/main/linux-virt-grsec/0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
@@ -1,14 +1,10 @@
-From patchwork Thu May 23 13:15:46 2013
-Content-Type: text/plain; charset="utf-8"
+From 87151ab93a08bcc4abe23aa2e87fbc2b956ae2cc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Mon, 27 May 2013 08:40:22 +0300
+Subject: [PATCH 6/6] ipv4: use next hop exceptions also for input routes
MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-Subject: [RFC] net/ipv4: Use next hop exceptions also for input routes
-Date: Thu, 23 May 2013 03:15:46 -0000
-From: =?utf-8?q?Timo_Ter=C3=A4s?= <timo.teras@iki.fi>
-X-Patchwork-Id: 245949
-Message-Id: <1369314946-12692-1-git-send-email-timo.teras@iki.fi>
-To: netdev@vger.kernel.org
-Cc: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Commit d2d68ba9 (ipv4: Cache input routes in fib_info nexthops)
assmued that "locally destined, and routed packets, never trigger
@@ -22,39 +18,23 @@ next hop exceptions are not consulted for pmtu, IP fragmentation will
not be done properly for these routes.
It also seems that we really need to have the PMTU information always
-for netfilter TCPMSS' clamp-to-pmtu feature to work properly.
+for netfilter TCPMSS clamp-to-pmtu feature to work properly.
So for the time being, cache separate copies of input routes for
each next hop exception.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
-
---
-I had ideas to make optimizations where pmtu information would not
-be needed. This includes:
-- Target devices with IFF_XMIT_DST_RELEASE set (practically all devices
- except tunnels). If skb_dst() is early freed the target device cannot
- generate PMTU events
-- Add flag for input route generation if pmtu info is needed for
- fragmentation. Basically a flag saying if DF bit was set in ip_hdr.
-
-However, TCPMSS clamp-to-pmtu prevents both optimizations.
-
-I'm not yet all familiar with the recent changes in routing caching,
-so there might be caveats that I missed. Basic testing shows this fixes
-the fragmentation issues I'm seeing, and I have not yet found any ill
-side effects either.
-
include/net/ip_fib.h | 3 ++-
net/ipv4/fib_semantics.c | 3 ++-
- net/ipv4/route.c | 41 +++++++++++++++++++++++++++++++----------
- 3 files changed, 35 insertions(+), 12 deletions(-)
+ net/ipv4/route.c | 65 +++++++++++++++++++++++++++++++++++++-----------
+ 3 files changed, 54 insertions(+), 17 deletions(-)
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
-index e49db91..20529a6 100644
+index 44424e9..aac8553 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
-@@ -55,7 +55,8 @@ struct fib_nh_exception {
+@@ -56,7 +56,8 @@ struct fib_nh_exception {
u32 fnhe_pmtu;
__be32 fnhe_gw;
unsigned long fnhe_expires;
@@ -79,45 +59,97 @@ index 8f6cb7a..d5dbca5 100644
kfree(fnhe);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
-index 550781a..073df96 100644
+index f44a4bb..a7a36f7 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
-@@ -576,9 +576,14 @@ static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
+@@ -565,10 +565,25 @@ static inline void rt_free(struct rtable *rt)
+
+ static DEFINE_SPINLOCK(fnhe_lock);
+
++static void fnhe_flush_routes(struct fib_nh_exception *fnhe)
++{
++ struct rtable *rt;
++
++ rt = rcu_dereference(fnhe->fnhe_rth_input);
++ if (rt) {
++ RCU_INIT_POINTER(fnhe->fnhe_rth_input, NULL);
++ rt_free(rt);
++ }
++ rt = rcu_dereference(fnhe->fnhe_rth_output);
++ if (rt) {
++ RCU_INIT_POINTER(fnhe->fnhe_rth_output, NULL);
++ rt_free(rt);
++ }
++}
++
+ static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
+ {
+ struct fib_nh_exception *fnhe, *oldest;
+- struct rtable *orig;
+
+ oldest = rcu_dereference(hash->chain);
+ for (fnhe = rcu_dereference(oldest->fnhe_next); fnhe;
+@@ -576,11 +591,7 @@ static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash)
if (time_before(fnhe->fnhe_stamp, oldest->fnhe_stamp))
oldest = fnhe;
}
- orig = rcu_dereference(oldest->fnhe_rth);
-+ orig = rcu_dereference(oldest->fnhe_rth_input);
- if (orig) {
+- if (orig) {
- RCU_INIT_POINTER(oldest->fnhe_rth, NULL);
-+ RCU_INIT_POINTER(oldest->fnhe_rth_input, NULL);
-+ rt_free(orig);
-+ }
-+ orig = rcu_dereference(oldest->fnhe_rth_output);
-+ if (orig) {
-+ RCU_INIT_POINTER(oldest->fnhe_rth_output, NULL);
- rt_free(orig);
- }
+- rt_free(orig);
+- }
++ fnhe_flush_routes(oldest);
return oldest;
-@@ -1209,7 +1214,15 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
+ }
+
+@@ -644,7 +655,10 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
+ fnhe->fnhe_expires = max(1UL, expires);
+ }
+ /* Update all cached dsts too */
+- rt = rcu_dereference(fnhe->fnhe_rth);
++ rt = rcu_dereference(fnhe->fnhe_rth_input);
++ if (rt)
++ fill_route_from_fnhe(rt, fnhe);
++ rt = rcu_dereference(fnhe->fnhe_rth_output);
+ if (rt)
+ fill_route_from_fnhe(rt, fnhe);
+ } else {
+@@ -668,6 +682,10 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
+ * stale, so anyone caching it rechecks if this exception
+ * applies to them.
+ */
++ rt = rcu_dereference(nh->nh_rth_input);
++ if (rt)
++ rt->dst.obsolete = DST_OBSOLETE_KILL;
++
+ for_each_possible_cpu(i) {
+ struct rtable __rcu **prt;
+ prt = per_cpu_ptr(nh->nh_pcpu_rth_output, i);
+@@ -1237,25 +1255,36 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
spin_lock_bh(&fnhe_lock);
if (daddr == fnhe->fnhe_daddr) {
-- struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
+ struct rtable __rcu **porig;
+ struct rtable *orig;
+ int genid = fnhe_genid(dev_net(rt->dst.dev));
+- struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
+
+ if (rt_is_input_route(rt))
+ porig = &fnhe->fnhe_rth_input;
+ else
+ porig = &fnhe->fnhe_rth_output;
-+
+ orig = rcu_dereference(*porig);
- if (orig && rt_is_expired(orig)) {
+
+ if (fnhe->fnhe_genid != genid) {
+ fnhe->fnhe_genid = genid;
fnhe->fnhe_gw = 0;
fnhe->fnhe_pmtu = 0;
-@@ -1231,12 +1244,14 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
- } else if (!rt->rt_gateway)
+ fnhe->fnhe_expires = 0;
++ fnhe_flush_routes(fnhe);
++ orig = NULL;
+ }
+ fill_route_from_fnhe(rt, fnhe);
+ if (!rt->rt_gateway)
rt->rt_gateway = daddr;
- rcu_assign_pointer(fnhe->fnhe_rth, rt);
@@ -135,7 +167,7 @@ index 550781a..073df96 100644
}
spin_unlock_bh(&fnhe_lock);
-@@ -1468,6 +1483,7 @@ static int __mkroute_input(struct sk_buff *skb,
+@@ -1487,6 +1516,7 @@ static int __mkroute_input(struct sk_buff *skb,
struct in_device *in_dev,
__be32 daddr, __be32 saddr, u32 tos)
{
@@ -143,7 +175,7 @@ index 550781a..073df96 100644
struct rtable *rth;
int err;
struct in_device *out_dev;
-@@ -1514,8 +1530,13 @@ static int __mkroute_input(struct sk_buff *skb,
+@@ -1533,8 +1563,13 @@ static int __mkroute_input(struct sk_buff *skb,
}
}
@@ -158,7 +190,7 @@ index 550781a..073df96 100644
if (rt_cache_valid(rth)) {
skb_dst_set_noref(skb, &rth->dst);
goto out;
-@@ -1543,7 +1564,7 @@ static int __mkroute_input(struct sk_buff *skb,
+@@ -1562,7 +1597,7 @@ static int __mkroute_input(struct sk_buff *skb,
rth->dst.input = ip_forward;
rth->dst.output = ip_output;
@@ -167,7 +199,7 @@ index 550781a..073df96 100644
skb_dst_set(skb, &rth->dst);
out:
err = 0;
-@@ -1858,7 +1879,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+@@ -1877,7 +1912,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
fnhe = find_exception(nh, fl4->daddr);
if (fnhe)
@@ -176,3 +208,6 @@ index 550781a..073df96 100644
else {
if (unlikely(fl4->flowi4_flags &
FLOWI_FLAG_KNOWN_NH &&
+--
+1.8.2.3
+
diff --git a/main/linux-virt-grsec/APKBUILD b/main/linux-virt-grsec/APKBUILD
index e1baab928b..81329e900a 100644
--- a/main/linux-virt-grsec/APKBUILD
+++ b/main/linux-virt-grsec/APKBUILD
@@ -1,15 +1,16 @@
-# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
+# Maintainer: Leonardo Arena <rnalrd@alpinelinux.org>
+# Maintainer: <bpiotrowski@alpinelinux.org>
_flavor=grsec
pkgname=linux-virt-${_flavor}
-pkgver=3.9.4
+pkgver=3.9.5
case $pkgver in
*.*.*) _kernver=${pkgver%.*};;
*.*) _kernver=${pkgver};;
esac
-pkgrel=3
+pkgrel=0
pkgdesc="Linux kernel with grsecurity"
-url=http://grsecurity.net
+url="http://grsecurity.net"
depends="mkinitfs linux-firmware"
makedepends="perl installkernel bash gmp-dev bc"
options="!strip"
@@ -17,13 +18,13 @@ _config=${config:-kernelconfig.${CARCH}}
install=
source="http://ftp.kernel.org/pub/linux/kernel/v3.x/linux-$_kernver.tar.xz
http://ftp.kernel.org/pub/linux/kernel/v3.x/patch-$pkgver.xz
- grsecurity-2.9.1-3.9.4-201306011536.patch
-
- v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
- leds-leds-gpio-reserve-gpio-before-using-it.patch
- ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch
- RFC-net-ipv4-Use-next-hop-exceptions-also-for-input-routes.patch
-
+ grsecurity-2.9.1-3.9.5-201306102218.patch
+ 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
+ 0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
+ 0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
+ 0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
+ 0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
+ 0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
kernelconfig.x86
kernelconfig.x86_64
"
@@ -147,29 +148,35 @@ dev() {
}
md5sums="4348c9b6b2eb3144d601e87c19d5d909 linux-3.9.tar.xz
-922c4553299e6692a28761d3032fc012 patch-3.9.4.xz
-08c33c99cb779ebd296d2b274c2deeda grsecurity-2.9.1-3.9.4-201306011536.patch
-699e92148cc9a55b6fc4d7d81e476717 v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
-83db7136608d8101ae130728539dc376 leds-leds-gpio-reserve-gpio-before-using-it.patch
-ac9a50bdbe91ba6e5205e83f7e734ff5 ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch
-12d3647755bebcd3b114f50de2729455 RFC-net-ipv4-Use-next-hop-exceptions-also-for-input-routes.patch
-2adad7226254e2c6c6c309e6f2100188 kernelconfig.x86
-308c29b96e311b3bbe5c01ee77c9cc71 kernelconfig.x86_64"
+aa22187ae5cd482a69097e9e59244491 patch-3.9.5.xz
+58dec4906c5abc6dc29355eb31816933 grsecurity-2.9.1-3.9.5-201306102218.patch
+a16f11b12381efb3bec79b9bfb329836 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
+656ae7b10dd2f18dbfa1011041d08d60 0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
+aa454ffb96428586447775c21449e284 0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
+2a12a3717052e878c0cd42aa935bfcf4 0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
+6ce5fed63aad3f1a1ff1b9ba7b741822 0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
+1a5800a2122ba0cc0d06733cb3bb8b8f 0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
+b89ff7921c1ecaf5b52bf4922a83333f kernelconfig.x86
+4248eb40a26207cda47091bec7868555 kernelconfig.x86_64"
sha256sums="60bc3e64ee5dc778de2cd7cd7640abf518a4c9d4f31b8ed624e16fad53f54541 linux-3.9.tar.xz
-694ea0d527556c5a214597596f37cdb598d2a0652d6f5e86b8c0de718990ccec patch-3.9.4.xz
-3bf95754ba94f3dfa7a91d92726e83c9092feab9e990f70d31bc52974bff27b0 grsecurity-2.9.1-3.9.4-201306011536.patch
-8e2f41605937eecd47cefe62daefd372dbf1e63cf956ab3ced3213ac2b508ee3 v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
-13676bc5610a8d03e788ac76734babd1338b023bb39559452ee54652b046e6f4 leds-leds-gpio-reserve-gpio-before-using-it.patch
-ab0dcb52342990ad05af5ce21acd1e95fb65cc7e76ec98e45c7ece7433bc9f23 ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch
-667babfafe4dc3449cd04853f532712188af557cbac41c461cf8236c4238f5a3 RFC-net-ipv4-Use-next-hop-exceptions-also-for-input-routes.patch
-dab9b80e559c4d9658dc858cdca66fdabfc7ac090e8a83c5d098065a4a32b547 kernelconfig.x86
-78852eac782c207a7488549bac06c8e6a01014efc9ead2ff9835cfc7743a851c kernelconfig.x86_64"
+f25145ff6ddde7a633839aabfd97b0d8239e14c494fd16210871229a35c1c0de patch-3.9.5.xz
+196ee8f6b9fc368ac7c09dc6f929e947f4a02b7ef66c2f84f00fa7f682774604 grsecurity-2.9.1-3.9.5-201306102218.patch
+6af3757ac36a6cd3cda7b0a71b08143726383b19261294a569ad7f4042c72df3 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
+dc8e82108615657f1fb9d641efd42255a5761c06edde1b00a41ae0d314d548f0 0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
+0985caa0f3ee8ed0959aeaa4214f5f8057ae8e61d50dcae39194912d31e14892 0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
+260fd1807838b68305a96992bf7d3302a2a8ef3a3b08fe079ba9a07e6422f736 0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
+ae32bb72afa170e6c3788c564b342763aba5945afacc1e2ebfc096adf50d77a3 0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
+fc613ac466610b866b721c41836fd5bfb2d4b75bceb67972dc6369d7f62ff47e 0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
+4a2856315aaeb9085c611f486ad2d899e3b13c67759456f4c62520cd5cc1565f kernelconfig.x86
+e70a59b4c86f901756d1cd343d9564d2d1159a7d65725c4b8ec8126f5a224e9c kernelconfig.x86_64"
sha512sums="77fa521f42380409f8ab400c26f7b00e225cb075ef40834bb263325cfdcc3e65aef8511ec2fc2b50bbf4f50e226fb5ab07d7a479aaf09162adbbf318325d0790 linux-3.9.tar.xz
-2a2eb511a610e8e3ddbc38b8bce0b96e60875009b7981542c98f0de3a601632a205fa9f90c6912094196dbda6536083b3990b28204c243a406f5595c40df0965 patch-3.9.4.xz
-eb326ded756cbe086c7999c5a982b6b695ae8ee3c25523a22acd480d97de0603d86eeef5252fe957ed5ccd4e7736db271a253264108e757b23a9bd3e82b32529 grsecurity-2.9.1-3.9.4-201306011536.patch
-772c847cd74b12ed22266042c0902d8a3cf09c897b6e1c01148dfcd2f01aed331f292e82c34bb718090dc0898e1ef364196272bff885a32378f7fbc8bfc06a9b v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
-10d2cf4fb308d1bc8cb5b9df3f9a6d7b9cef453244673bcbe66bd9b64af410a498e203d4dfa51f53461362ad981736eadc46537616b2c0514f57f4d8864c830d leds-leds-gpio-reserve-gpio-before-using-it.patch
-769291e92f2f5ae5375d98b80bf8790b089c87437f1660cf8d5e9d45d7221280b6824bcb1d2564cbe12310a88df48443c56ecc9ce5468858829088221aa80327 ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch
-d35c939967d5696e477e2c5181f96e9cb92e1db88477576615f36209d276e0a2a866111d43e4abe076c455e32b063d6a97d42e5bc9ca04702d78b13826bf3afb RFC-net-ipv4-Use-next-hop-exceptions-also-for-input-routes.patch
-7ee22fe997767502a46338d2fa1921cf5a285372facb316eed76f85c7f1e480cef64e6a2c361e2c08136d3ceae8bcc1897d420ecc70fc84e9c81040728c34e85 kernelconfig.x86
-9d394eaab29b1557a486346079920ca909e66f1fd76c90c1b4713de31c248d0bf19cb9170917149f7a634d7701b425b9777c92bd70dffdb2a4212a7373478fba kernelconfig.x86_64"
+8e9a064adadd062c7ca52c44de19dfd46b029e60f2832988a606e086b669ea699861ec57732d4abfb16e486f767d123fcfd66da7c2ddde380b7c13582bb44983 patch-3.9.5.xz
+704f65e048888c64aa02214e80103745f16f2ddebe9e8304331208436481ca6b1fcadc2e862203142ac98b6d5f7c409ba542b68c11775c4e7ba765a63b3ab2a6 grsecurity-2.9.1-3.9.5-201306102218.patch
+81e78593288e8b0fd2c03ea9fc1450323887707f087e911f172450a122bc9b591ee83394836789730d951aeec13d0b75a64e1c05f04364abf8f80d883ddc4a02 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch
+51ecb15b669f6a82940a13a38939116e003bf5dfd24496771c8279e907b72adcc63d607f0340a2940d757e12ddadb7d45c7af78ae311d284935a6296dbcac00c 0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch
+57d0a8bd35d19cf657ded58efe24517d2252aec6984040713ba173a34edb5887ececaa2985076bc6a149eaa57639fd98a042c1c2d226ed4ad8dd5ed0e230717e 0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch
+d2f578ad1d6e1fe52b55863e5bf338ae8201b828a498ec3e42e549c55295d3d1c6c3adfa9e226d711e3486628ed56ab996484e219d79ac4b0c0ec684ebd380aa 0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch
+28a33e644bf2faf99c8dd6dbccfe14e140dfdd8824a8fb2d58aa7deb9e572f130d92b6b35ee181084050d82166bdf2e498a451a2a538a67b7ab84204405d2d87 0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch
+249140374c19a5599876268ff5b3cda2e136681aee103b4a9fff5d7d346f8e3295a907fb43db0701b8a9fece64c299ad2abac0434259cce6631307ce84090205 0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch
+ea5de61204ccc4611272d1b1a95f8ff0a36e9518587282df2c9e488c3425083a59c695be62b2920b9015e615c9298d76db7d821080ee80f83ff2ccdd58241539 kernelconfig.x86
+c7e7f403cb3e16f315eb26063035a1bc65e101ca0dada2dcadac9c11989f4b434753bbfe7cac6abbc67680a3945c7244649f1f05c844ac5ed48f571037daf694 kernelconfig.x86_64"
diff --git a/main/linux-virt-grsec/grsecurity-2.9.1-3.9.4-201306011536.patch b/main/linux-virt-grsec/grsecurity-2.9.1-3.9.5-201306102218.patch
index 9a1a55c812..49e438f1bb 100644
--- a/main/linux-virt-grsec/grsecurity-2.9.1-3.9.4-201306011536.patch
+++ b/main/linux-virt-grsec/grsecurity-2.9.1-3.9.5-201306102218.patch
@@ -259,7 +259,7 @@ index 8ccbf27..afffeb4 100644
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index bfbfaf9..d0b1bb8 100644
+index 8818c95..ced0bb1 100644
--- a/Makefile
+++ b/Makefile
@@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -3390,7 +3390,7 @@ index 044c31d..2ee0861 100644
struct omap_device *omap_device_alloc(struct platform_device *pdev,
struct omap_hwmod **ohs, int oh_cnt);
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
-index a202a47..c430564 100644
+index 3a750de..4c9b88f 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -191,10 +191,10 @@ struct omap_hwmod_soc_ops {
@@ -5763,6 +5763,19 @@ index e0a8235..ce2f1e1 100644
ret = __copy_from_user(to, from, n);
else
copy_from_user_overflow();
+diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
+index 5709c5e..14285ca 100644
+--- a/arch/parisc/kernel/drivers.c
++++ b/arch/parisc/kernel/drivers.c
+@@ -394,7 +394,7 @@ EXPORT_SYMBOL(print_pci_hwpath);
+ static void setup_bus_id(struct parisc_device *padev)
+ {
+ struct hardware_path path;
+- char name[20];
++ char name[28];
+ char *output = name;
+ int i;
+
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 2a625fb..9908930 100644
--- a/arch/parisc/kernel/module.c
@@ -5866,6 +5879,20 @@ index 2a625fb..9908930 100644
DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
me->arch.unwind_section, table, end, gp);
+diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
+index a3328c2..3b812eb 100644
+--- a/arch/parisc/kernel/setup.c
++++ b/arch/parisc/kernel/setup.c
+@@ -69,7 +69,8 @@ void __init setup_cmdline(char **cmdline_p)
+ /* called from hpux boot loader */
+ boot_command_line[0] = '\0';
+ } else {
+- strcpy(boot_command_line, (char *)__va(boot_args[1]));
++ strlcpy(boot_command_line, (char *)__va(boot_args[1]),
++ COMMAND_LINE_SIZE);
+
+ #ifdef CONFIG_BLK_DEV_INITRD
+ if (boot_args[2] != 0) /* did palo pass us a ramdisk? */
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 5dfd248..64914ac 100644
--- a/arch/parisc/kernel/sys_parisc.c
@@ -6353,10 +6380,10 @@ index 4aad413..85d86bf 100644
#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
-index c9c67fc..e10c012 100644
+index 3b097a8..8f8c774 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
-@@ -245,6 +245,7 @@
+@@ -234,6 +234,7 @@
#define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
#define DSISR_NOHPTE 0x40000000 /* no translation found */
@@ -6790,10 +6817,10 @@ index f9b30c6..d72e7a3 100644
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
-index 95068bf..9ba1814 100644
+index 201385c..0f01828 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
-@@ -982,7 +982,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
+@@ -976,7 +976,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
addr = frame;
@@ -6803,10 +6830,10 @@ index 95068bf..9ba1814 100644
tramp = current->mm->context.vdso_base + vdso32_rt_sigtramp;
} else {
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
-index c179428..58acdaa 100644
+index 3459473..2d40783 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
-@@ -758,7 +758,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
+@@ -749,7 +749,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
#endif
/* Set up to return from userspace. */
@@ -6829,10 +6856,10 @@ index 3ce1f86..c30e629 100644
};
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
-index 83efa2f..6bb5839 100644
+index 1c22b2d..3b56e67 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
-@@ -141,6 +141,8 @@ static unsigned __kprobes long oops_begin(struct pt_regs *regs)
+@@ -142,6 +142,8 @@ static unsigned __kprobes long oops_begin(struct pt_regs *regs)
return flags;
}
@@ -6841,7 +6868,7 @@ index 83efa2f..6bb5839 100644
static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
int signr)
{
-@@ -190,6 +192,9 @@ static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
+@@ -191,6 +193,9 @@ static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
panic("Fatal exception in interrupt");
if (panic_on_oops)
panic("Fatal exception");
@@ -20475,7 +20502,7 @@ index 73afd11..d1670f5 100644
+ .fill PAGE_SIZE_asm - GDT_SIZE,1,0
+ .endr
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
-index 08f7e80..40cbed5 100644
+index 321d65e..e9437f7 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -20,6 +20,8 @@
@@ -20516,7 +20543,7 @@ index 08f7e80..40cbed5 100644
/*
* Set up the identity mapping for the switchover. These
-@@ -175,8 +187,8 @@ ENTRY(secondary_startup_64)
+@@ -177,8 +189,8 @@ ENTRY(secondary_startup_64)
movq $(init_level4_pgt - __START_KERNEL_map), %rax
1:
@@ -20527,7 +20554,7 @@ index 08f7e80..40cbed5 100644
movq %rcx, %cr4
/* Setup early boot stage 4 level pagetables. */
-@@ -197,10 +209,18 @@ ENTRY(secondary_startup_64)
+@@ -199,10 +211,18 @@ ENTRY(secondary_startup_64)
movl $MSR_EFER, %ecx
rdmsr
btsl $_EFER_SCE, %eax /* Enable System Call */
@@ -20547,7 +20574,7 @@ index 08f7e80..40cbed5 100644
1: wrmsr /* Make changes effective */
/* Setup cr0 */
-@@ -280,6 +300,7 @@ ENTRY(secondary_startup_64)
+@@ -282,6 +302,7 @@ ENTRY(secondary_startup_64)
* REX.W + FF /5 JMP m16:64 Jump far, absolute indirect,
* address given in m16:64.
*/
@@ -20555,7 +20582,7 @@ index 08f7e80..40cbed5 100644
movq initial_code(%rip),%rax
pushq $0 # fake return address to stop unwinder
pushq $__KERNEL_CS # set correct cs
-@@ -386,7 +407,7 @@ ENTRY(early_idt_handler)
+@@ -388,7 +409,7 @@ ENTRY(early_idt_handler)
call dump_stack
#ifdef CONFIG_KALLSYMS
leaq early_idt_ripmsg(%rip),%rdi
@@ -20564,7 +20591,7 @@ index 08f7e80..40cbed5 100644
call __print_symbol
#endif
#endif /* EARLY_PRINTK */
-@@ -414,6 +435,7 @@ ENDPROC(early_idt_handler)
+@@ -416,6 +437,7 @@ ENDPROC(early_idt_handler)
early_recursion_flag:
.long 0
@@ -20572,7 +20599,7 @@ index 08f7e80..40cbed5 100644
#ifdef CONFIG_EARLY_PRINTK
early_idt_msg:
.asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
-@@ -443,27 +465,50 @@ NEXT_PAGE(early_dynamic_pgts)
+@@ -445,27 +467,50 @@ NEXT_PAGE(early_dynamic_pgts)
.data
@@ -20631,7 +20658,7 @@ index 08f7e80..40cbed5 100644
NEXT_PAGE(level3_kernel_pgt)
.fill L3_START_KERNEL,8,0
-@@ -471,6 +516,9 @@ NEXT_PAGE(level3_kernel_pgt)
+@@ -473,6 +518,9 @@ NEXT_PAGE(level3_kernel_pgt)
.quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
.quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
@@ -20641,7 +20668,7 @@ index 08f7e80..40cbed5 100644
NEXT_PAGE(level2_kernel_pgt)
/*
* 512 MB kernel mapping. We spend a full page on this pagetable
-@@ -486,38 +534,64 @@ NEXT_PAGE(level2_kernel_pgt)
+@@ -488,38 +536,64 @@ NEXT_PAGE(level2_kernel_pgt)
KERNEL_IMAGE_SIZE/PMD_SIZE)
NEXT_PAGE(level2_fixmap_pgt)
@@ -20743,10 +20770,10 @@ index 0fa6912..37fce70 100644
+EXPORT_SYMBOL(__LOAD_PHYSICAL_ADDR);
+#endif
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
-index 245a71d..89d9ce4 100644
+index cb33909..1163b40 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
-@@ -55,7 +55,7 @@ static inline bool interrupted_kernel_fpu_idle(void)
+@@ -51,7 +51,7 @@ static inline bool interrupted_kernel_fpu_idle(void)
static inline bool interrupted_user_mode(void)
{
struct pt_regs *regs = get_irq_regs();
@@ -23943,7 +23970,7 @@ index a20ecb5..d0e2194 100644
out:
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
-index 59622c9..f338414 100644
+index 698eece..776b682 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -328,6 +328,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
@@ -31882,10 +31909,10 @@ index 34c8216..f56c828 100644
unsigned long timeout_msec)
{
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
-index 63c743b..0422dc6 100644
+index cf15aee..e0b7078 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
-@@ -4786,7 +4786,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
+@@ -4792,7 +4792,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
struct ata_port *ap;
unsigned int tag;
@@ -31894,7 +31921,7 @@ index 63c743b..0422dc6 100644
ap = qc->ap;
qc->flags = 0;
-@@ -4802,7 +4802,7 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
+@@ -4808,7 +4808,7 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
struct ata_port *ap;
struct ata_link *link;
@@ -31903,7 +31930,7 @@ index 63c743b..0422dc6 100644
WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE));
ap = qc->ap;
link = qc->dev->link;
-@@ -5920,6 +5920,7 @@ static void ata_finalize_port_ops(struct ata_port_operations *ops)
+@@ -5926,6 +5926,7 @@ static void ata_finalize_port_ops(struct ata_port_operations *ops)
return;
spin_lock(&lock);
@@ -31911,7 +31938,7 @@ index 63c743b..0422dc6 100644
for (cur = ops->inherits; cur; cur = cur->inherits) {
void **inherit = (void **)cur;
-@@ -5933,8 +5934,9 @@ static void ata_finalize_port_ops(struct ata_port_operations *ops)
+@@ -5939,8 +5940,9 @@ static void ata_finalize_port_ops(struct ata_port_operations *ops)
if (IS_ERR(*pp))
*pp = NULL;
@@ -31951,7 +31978,7 @@ index f9b983a..887b9d8 100644
return 0;
}
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
-index 77a7480..05cde58 100644
+index 77a7480d..05cde58 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -454,7 +454,7 @@ static void tx_complete (amb_dev * dev, tx_out * tx) {
@@ -33220,7 +33247,7 @@ index 7fda30e..eb5dfe0 100644
/* queue and queue Info */
struct list_head reqQ;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
-index 3f08713..56a586a 100644
+index 3f08713..87d4b4a 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -404,7 +404,7 @@ static int cpqarray_register_ctlr(int i, struct pci_dev *pdev)
@@ -33295,7 +33322,15 @@ index 3f08713..56a586a 100644
a1 = a; a &= ~3;
if ((c = h->cmpQ) == NULL)
{
-@@ -1449,11 +1449,11 @@ static int sendcmd(
+@@ -1195,6 +1195,7 @@ out_passthru:
+ ida_pci_info_struct pciinfo;
+
+ if (!arg) return -EINVAL;
++ memset(&pciinfo, 0, sizeof(pciinfo));
+ pciinfo.bus = host->pci_dev->bus->number;
+ pciinfo.dev_fn = host->pci_dev->devfn;
+ pciinfo.board_id = host->board_id;
+@@ -1449,11 +1450,11 @@ static int sendcmd(
/*
* Disable interrupt
*/
@@ -33309,7 +33344,7 @@ index 3f08713..56a586a 100644
if (temp != 0) {
break;
}
-@@ -1466,7 +1466,7 @@ DBG(
+@@ -1466,7 +1467,7 @@ DBG(
/*
* Send the cmd
*/
@@ -33318,7 +33353,7 @@ index 3f08713..56a586a 100644
complete = pollcomplete(ctlr);
pci_unmap_single(info_p->pci_dev, (dma_addr_t) c->req.sg[0].addr,
-@@ -1549,9 +1549,9 @@ static int revalidate_allvol(ctlr_info_t *host)
+@@ -1549,9 +1550,9 @@ static int revalidate_allvol(ctlr_info_t *host)
* we check the new geometry. Then turn interrupts back on when
* we're done.
*/
@@ -33330,7 +33365,7 @@ index 3f08713..56a586a 100644
for(i=0; i<NWD; i++) {
struct gendisk *disk = ida_gendisk[ctlr][i];
-@@ -1591,7 +1591,7 @@ static int pollcomplete(int ctlr)
+@@ -1591,7 +1592,7 @@ static int pollcomplete(int ctlr)
/* Wait (up to 2 seconds) for a command to complete */
for (i = 200000; i > 0; i--) {
@@ -33542,7 +33577,7 @@ index 2e7de7a..ed86dc0 100644
static DEFINE_MUTEX(pktcdvd_mutex);
static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
-index d620b44..587561e 100644
+index d620b44..e9abc80 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -416,7 +416,6 @@ int register_cdrom(struct cdrom_device_info *cdi)
@@ -33575,6 +33610,24 @@ index d620b44..587561e 100644
cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
}
+@@ -2107,7 +2108,7 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
+ */
+ nr = nframes;
+ do {
+- cgc.buffer = kmalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL);
++ cgc.buffer = kzalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL);
+ if (cgc.buffer)
+ break;
+
+@@ -2882,7 +2883,7 @@ static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi,
+ if (lba < 0)
+ return -EINVAL;
+
+- cgc->buffer = kmalloc(blocksize, GFP_KERNEL);
++ cgc->buffer = kzalloc(blocksize, GFP_KERNEL);
+ if (cgc->buffer == NULL)
+ return -ENOMEM;
+
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index d59cdcb..11afddf 100644
--- a/drivers/cdrom/gdrom.c
@@ -33882,6 +33935,18 @@ index 2c644af..d4d7f17 100644
};
static int memory_open(struct inode *inode, struct file *filp)
+diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
+index c689697..04e6d6a 100644
+--- a/drivers/char/mwave/tp3780i.c
++++ b/drivers/char/mwave/tp3780i.c
+@@ -479,6 +479,7 @@ int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities
+ PRINTK_2(TRACE_TP3780I,
+ "tp3780i::tp3780I_QueryAbilities entry pBDData %p\n", pBDData);
+
++ memset(pAbilities, 0, sizeof(*pAbilities));
+ /* fill out standard constant fields */
+ pAbilities->instr_per_sec = pBDData->rDspSettings.uIps;
+ pAbilities->data_size = pBDData->rDspSettings.uDStoreSize;
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 9df78e2..01ba9ae 100644
--- a/drivers/char/nvram.c
@@ -33971,7 +34036,7 @@ index 5c5cc00..ac9edb7 100644
if (cmd != SIOCWANDEV)
diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 32a6c57..98038d5 100644
+index eccd7cc..98038d5 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -272,8 +272,13 @@
@@ -34017,85 +34082,7 @@ index 32a6c57..98038d5 100644
smp_wmb();
if (out)
-@@ -865,16 +877,24 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
- if (r->entropy_count / 8 < min + reserved) {
- nbytes = 0;
- } else {
-+ int entropy_count, orig;
-+retry:
-+ entropy_count = orig = ACCESS_ONCE(r->entropy_count);
- /* If limited, never pull more than available */
-- if (r->limit && nbytes + reserved >= r->entropy_count / 8)
-- nbytes = r->entropy_count/8 - reserved;
-+ if (r->limit && nbytes + reserved >= entropy_count / 8)
-+ nbytes = entropy_count/8 - reserved;
-
-- if (r->entropy_count / 8 >= nbytes + reserved)
-- r->entropy_count -= nbytes*8;
-- else
-- r->entropy_count = reserved;
-+ if (entropy_count / 8 >= nbytes + reserved) {
-+ entropy_count -= nbytes*8;
-+ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
-+ goto retry;
-+ } else {
-+ entropy_count = reserved;
-+ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
-+ goto retry;
-+ }
-
-- if (r->entropy_count < random_write_wakeup_thresh)
-+ if (entropy_count < random_write_wakeup_thresh)
- wakeup_write = 1;
- }
-
-@@ -957,10 +977,23 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
- {
- ssize_t ret = 0, i;
- __u8 tmp[EXTRACT_SIZE];
-+ unsigned long flags;
-
- /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
-- if (fips_enabled && !r->last_data_init)
-- nbytes += EXTRACT_SIZE;
-+ if (fips_enabled) {
-+ spin_lock_irqsave(&r->lock, flags);
-+ if (!r->last_data_init) {
-+ r->last_data_init = true;
-+ spin_unlock_irqrestore(&r->lock, flags);
-+ trace_extract_entropy(r->name, EXTRACT_SIZE,
-+ r->entropy_count, _RET_IP_);
-+ xfer_secondary_pool(r, EXTRACT_SIZE);
-+ extract_buf(r, tmp);
-+ spin_lock_irqsave(&r->lock, flags);
-+ memcpy(r->last_data, tmp, EXTRACT_SIZE);
-+ }
-+ spin_unlock_irqrestore(&r->lock, flags);
-+ }
-
- trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
- xfer_secondary_pool(r, nbytes);
-@@ -970,19 +1003,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
- extract_buf(r, tmp);
-
- if (fips_enabled) {
-- unsigned long flags;
--
--
-- /* prime last_data value if need be, per fips 140-2 */
-- if (!r->last_data_init) {
-- spin_lock_irqsave(&r->lock, flags);
-- memcpy(r->last_data, tmp, EXTRACT_SIZE);
-- r->last_data_init = true;
-- nbytes -= EXTRACT_SIZE;
-- spin_unlock_irqrestore(&r->lock, flags);
-- extract_buf(r, tmp);
-- }
--
- spin_lock_irqsave(&r->lock, flags);
- if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
- panic("Hardware RNG duplicated output!\n");
-@@ -1024,7 +1044,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+@@ -1032,7 +1044,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
extract_buf(r, tmp);
i = min_t(int, nbytes, EXTRACT_SIZE);
@@ -34104,7 +34091,7 @@ index 32a6c57..98038d5 100644
ret = -EFAULT;
break;
}
-@@ -1360,7 +1380,7 @@ EXPORT_SYMBOL(generate_random_uuid);
+@@ -1368,7 +1380,7 @@ EXPORT_SYMBOL(generate_random_uuid);
#include <linux/sysctl.h>
static int min_read_thresh = 8, min_write_thresh;
@@ -34113,7 +34100,7 @@ index 32a6c57..98038d5 100644
static int max_write_thresh = INPUT_POOL_WORDS * 32;
static char sysctl_bootid[16];
-@@ -1376,7 +1396,7 @@ static char sysctl_bootid[16];
+@@ -1384,7 +1396,7 @@ static char sysctl_bootid[16];
static int proc_do_uuid(ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -35743,10 +35730,10 @@ index 5a82b6b..9e69c73 100644
if (regcomp
(&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
-index 44b8034..cc722fd 100644
+index 5073665..31d15a6 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
-@@ -977,7 +977,7 @@ static bool radeon_switcheroo_can_switch(struct pci_dev *pdev)
+@@ -976,7 +976,7 @@ static bool radeon_switcheroo_can_switch(struct pci_dev *pdev)
bool can_switch;
spin_lock(&dev->count_lock);
@@ -37505,6 +37492,37 @@ index 89562a8..218999b 100644
capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */
capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */
capimsg_setu16(skb->data, 16, len); /* Data length */
+diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
+index 9b1b274..c123709 100644
+--- a/drivers/isdn/capi/kcapi.c
++++ b/drivers/isdn/capi/kcapi.c
+@@ -93,7 +93,7 @@ capi_ctr_put(struct capi_ctr *ctr)
+
+ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
+ {
+- if (contr - 1 >= CAPI_MAXCONTR)
++ if (contr < 1 || contr - 1 >= CAPI_MAXCONTR)
+ return NULL;
+
+ return capi_controller[contr - 1];
+@@ -103,7 +103,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
+ {
+ lockdep_assert_held(&capi_controller_lock);
+
+- if (applid - 1 >= CAPI_MAXAPPL)
++ if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
+ return NULL;
+
+ return capi_applications[applid - 1];
+@@ -111,7 +111,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
+
+ static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
+ {
+- if (applid - 1 >= CAPI_MAXAPPL)
++ if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
+ return NULL;
+
+ return rcu_dereference(capi_applications[applid - 1]);
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index e2b5396..c5486dc 100644
--- a/drivers/isdn/gigaset/interface.c
@@ -39597,7 +39615,7 @@ index ff90760..08d8aed 100644
/**
* bnx2x_config_rx_mode - Send and RX_MODE ramrod according to the provided parameters.
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
-index 8d7d4c2..95f7681 100644
+index 25309bf..fcfd54c 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -147,6 +147,7 @@
@@ -40506,10 +40524,10 @@ index 12c4f31..484d948 100644
memset(buf, 0, sizeof(buf));
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
-index cffdf4f..7cefb69 100644
+index 2b49f48..14fc244 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
-@@ -2144,25 +2144,19 @@ static int __init init_mac80211_hwsim(void)
+@@ -2143,25 +2143,19 @@ static int __init init_mac80211_hwsim(void)
if (channels > 1) {
hwsim_if_comb.num_different_channels = channels;
@@ -42680,7 +42698,7 @@ index 5f13890..36a044b 100644
pDevice->apdev->type = ARPHRD_IEEE80211;
diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c
-index bc5e9da..dacd556 100644
+index a94e66f..31984d0 100644
--- a/drivers/staging/vt6656/hostap.c
+++ b/drivers/staging/vt6656/hostap.c
@@ -60,14 +60,13 @@ static int msglevel =MSG_LEVEL_INFO;
@@ -42751,48 +42769,6 @@ index adbe5a8..d387359 100644
extern void tmem_register_hostops(struct tmem_hostops *m);
/* core tmem accessor functions */
-diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
-index ca2be40..93ae910 100644
---- a/drivers/target/iscsi/iscsi_target_parameters.c
-+++ b/drivers/target/iscsi/iscsi_target_parameters.c
-@@ -712,9 +712,9 @@ static int iscsi_add_notunderstood_response(
- }
- INIT_LIST_HEAD(&extra_response->er_list);
-
-- strncpy(extra_response->key, key, strlen(key) + 1);
-- strncpy(extra_response->value, NOTUNDERSTOOD,
-- strlen(NOTUNDERSTOOD) + 1);
-+ strlcpy(extra_response->key, key, sizeof(extra_response->key));
-+ strlcpy(extra_response->value, NOTUNDERSTOOD,
-+ sizeof(extra_response->value));
-
- list_add_tail(&extra_response->er_list,
- &param_list->extra_response_list);
-@@ -1583,8 +1583,6 @@ int iscsi_decode_text_input(
-
- if (phase & PHASE_SECURITY) {
- if (iscsi_check_for_auth_key(key) > 0) {
-- char *tmpptr = key + strlen(key);
-- *tmpptr = '=';
- kfree(tmpbuf);
- return 1;
- }
-diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h
-index 1e1b750..2c536a0 100644
---- a/drivers/target/iscsi/iscsi_target_parameters.h
-+++ b/drivers/target/iscsi/iscsi_target_parameters.h
-@@ -1,8 +1,10 @@
- #ifndef ISCSI_PARAMETERS_H
- #define ISCSI_PARAMETERS_H
-
-+#include <scsi/iscsi_proto.h>
-+
- struct iscsi_extra_response {
-- char key[64];
-+ char key[KEY_MAXLEN];
- char value[32];
- struct list_head er_list;
- } ____cacheline_aligned;
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 2e4d655..fd72e68 100644
--- a/drivers/target/target_core_device.c
@@ -42807,10 +42783,10 @@ index 2e4d655..fd72e68 100644
spin_lock_init(&dev->t10_wwn.t10_vpd_lock);
INIT_LIST_HEAD(&dev->t10_pr.registration_list);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
-index 0d46276..f327cab5 100644
+index fc9a5a0..1d5975e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
-@@ -1080,7 +1080,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd)
+@@ -1081,7 +1081,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd)
* Used to determine when ORDERED commands should go from
* Dormant to Active status.
*/
@@ -43153,10 +43129,10 @@ index 4a43ef5d7..aa71f27 100644
dlci_get(dlci->gsm->dlci[0]);
mux_get(dlci->gsm);
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
-index 05e72be..67f6a0f 100644
+index 1f8cba6..47b06c2 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
-@@ -2197,6 +2197,7 @@ void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
+@@ -2205,6 +2205,7 @@ void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
{
*ops = tty_ldisc_N_TTY;
ops->owner = NULL;
@@ -44078,7 +44054,7 @@ index c8b9262..7e824e6 100644
ret = uio_get_minor(idev);
if (ret)
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
-index b7eb86a..c00402f 100644
+index 8a7eb77..c00402f 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -473,7 +473,7 @@ static ssize_t cxacru_sysfs_store_adsl_config(struct device *dev,
@@ -44090,16 +44066,6 @@ index b7eb86a..c00402f 100644
return -EINVAL;
pos += tmp;
-@@ -686,7 +686,8 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ
- {
- int ret, len;
- __le32 *buf;
-- int offb, offd;
-+ int offb;
-+ unsigned int offd;
- const int stride = CMD_PACKET_SIZE / (4 * 2) - 1;
- int buflen = ((size - 1) / stride + 1 + size * 2) * 4;
-
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 35f10bf..6a38a0b 100644
--- a/drivers/usb/atm/usbatm.c
@@ -51161,39 +51127,6 @@ index febbe0e..782c4fd 100644
static int parse_strtoul(const char *buf,
unsigned long max, unsigned long *value)
-diff --git a/fs/fat/inode.c b/fs/fat/inode.c
-index acf6e47..e7a7fde 100644
---- a/fs/fat/inode.c
-+++ b/fs/fat/inode.c
-@@ -1223,6 +1223,19 @@ static int fat_read_root(struct inode *inode)
- return 0;
- }
-
-+static unsigned long calc_fat_clusters(struct super_block *sb)
-+{
-+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
-+
-+ /* Divide first to avoid overflow */
-+ if (sbi->fat_bits != 12) {
-+ unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits;
-+ return ent_per_sec * sbi->fat_length;
-+ }
-+
-+ return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
-+}
-+
- /*
- * Read the super block of an MS-DOS FS.
- */
-@@ -1427,7 +1440,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
- sbi->dirty = b->fat16.state & FAT_STATE_DIRTY;
-
- /* check that FAT table does not overflow */
-- fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
-+ fat_clusters = calc_fat_clusters(sb);
- total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
- if (total_clusters > MAX_FAT(sb)) {
- if (!silent)
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 6599222..e7bf0de 100644
--- a/fs/fcntl.c
@@ -52844,10 +52777,10 @@ index 11dfa0c..6f64416 100644
if (!ret)
ret = -EPIPE;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
-index ff15522..092a0f6 100644
+index 185c479..51b9986 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
-@@ -1409,7 +1409,7 @@ static char *read_link(struct dentry *dentry)
+@@ -1415,7 +1415,7 @@ static char *read_link(struct dentry *dentry)
return link;
}
@@ -53940,10 +53873,18 @@ index e7bc1d7..06bd4bb 100644
}
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
-index 5d84442..bf24453 100644
+index 5d84442..2c034ba 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
-@@ -251,8 +251,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
+@@ -121,6 +121,7 @@ static int fill_event_metadata(struct fsnotify_group *group,
+ metadata->event_len = FAN_EVENT_METADATA_LEN;
+ metadata->metadata_len = FAN_EVENT_METADATA_LEN;
+ metadata->vers = FANOTIFY_METADATA_VERSION;
++ metadata->reserved = 0;
+ metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS;
+ metadata->pid = pid_vnr(event->tgid);
+ if (unlikely(event->mask & FAN_Q_OVERFLOW))
+@@ -251,8 +252,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
fd = fanotify_event_metadata.fd;
ret = -EFAULT;
@@ -56526,7 +56467,7 @@ index d681e34..2a3f5ab 100644
goto out_put;
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
-index d82efaa..0904a8e 100644
+index ca9ecaa..60100c7 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -395,7 +395,7 @@ xfs_vn_put_link(
@@ -56540,10 +56481,10 @@ index d82efaa..0904a8e 100644
kfree(s);
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..7174794
+index 0000000..ba9c5e3
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,1031 @@
+@@ -0,0 +1,1053 @@
+#
+# grecurity configuration
+#
@@ -56629,6 +56570,25 @@ index 0000000..7174794
+ If you're using KERNEXEC, it's recommended that you enable this option
+ to supplement the hardening of the kernel.
+
++config GRKERNSEC_PERF_HARDEN
++ bool "Disable unprivileged PERF_EVENTS usage by default"
++ default y if GRKERNSEC_CONFIG_AUTO
++ depends on PERF_EVENTS
++ help
++ If you say Y here, the range of acceptable values for the
++ /proc/sys/kernel/perf_event_paranoid sysctl will be expanded to allow and
++ default to a new value: 3. When the sysctl is set to this value, no
++ unprivileged use of the PERF_EVENTS syscall interface will be permitted.
++
++ Though PERF_EVENTS can be used legitimately for performance monitoring
++ and low-level application profiling, it is forced on regardless of
++ configuration, has been at fault for several vulnerabilities, and
++ creates new opportunities for side channels and other information leaks.
++
++ This feature puts PERF_EVENTS into a secure default state and permits
++ the administrator to change out of it temporarily if unprivileged
++ application profiling is needed.
++
+config GRKERNSEC_RAND_THREADSTACK
+ bool "Insert random gaps between thread stacks"
+ default y if GRKERNSEC_CONFIG_AUTO
@@ -56739,6 +56699,9 @@ index 0000000..7174794
+ useful protection against local kernel exploitation of overflows
+ and arbitrary read/write vulnerabilities.
+
++ It is highly recommended that you enable GRKERNSEC_PERF_HARDEN
++ in addition to this feature.
++
+config GRKERNSEC_KERN_LOCKOUT
+ bool "Active kernel exploit response"
+ default y if GRKERNSEC_CONFIG_AUTO
@@ -70441,7 +70404,7 @@ index 45fc162..01a4068 100644
/**
* struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
-index 1d795df..727aa7b 100644
+index 1d795df..b0a6449 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -333,8 +333,8 @@ struct perf_event {
@@ -70475,8 +70438,15 @@ index 1d795df..727aa7b 100644
extern int sysctl_perf_event_mlock;
extern int sysctl_perf_event_sample_rate;
-@@ -714,17 +714,17 @@ extern int perf_proc_update_handler(struct ctl_table *table, int write,
+@@ -712,19 +712,24 @@ extern int perf_proc_update_handler(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos);
++static inline bool perf_paranoid_any(void)
++{
++ return sysctl_perf_event_legitimately_concerned > 2;
++}
++
static inline bool perf_paranoid_tracepoint_raw(void)
{
- return sysctl_perf_event_paranoid > -1;
@@ -70496,7 +70466,7 @@ index 1d795df..727aa7b 100644
}
extern void perf_event_init(void);
-@@ -812,7 +812,7 @@ static inline void perf_restore_debug_store(void) { }
+@@ -812,7 +817,7 @@ static inline void perf_restore_debug_store(void) { }
*/
#define perf_cpu_notifier(fn) \
do { \
@@ -70505,7 +70475,7 @@ index 1d795df..727aa7b 100644
{ .notifier_call = fn, .priority = CPU_PRI_PERF }; \
unsigned long cpu = smp_processor_id(); \
unsigned long flags; \
-@@ -831,7 +831,7 @@ do { \
+@@ -831,7 +836,7 @@ do { \
struct perf_pmu_events_attr {
struct device_attribute attr;
u64 id;
@@ -72906,10 +72876,10 @@ index a6a059c..2243336 100644
struct snd_soc_platform {
const char *name;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
-index c4af592..20c52d2 100644
+index f8640f3..b72d113 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
-@@ -657,7 +657,7 @@ struct se_device {
+@@ -658,7 +658,7 @@ struct se_device {
spinlock_t stats_lock;
/* Active commands on this virtual SE device */
atomic_t simple_cmds;
@@ -74209,10 +74179,10 @@ index f6c2ce5..982c0f9 100644
+ return ns_capable_nolog(ns, cap) && kuid_has_mapping(ns, inode->i_uid);
+}
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
-index ba1f977..f840d9c 100644
+index a48de6a..df24bfe 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
-@@ -5569,7 +5569,7 @@ static int cgroup_css_links_read(struct cgroup *cont,
+@@ -5567,7 +5567,7 @@ static int cgroup_css_links_read(struct cgroup *cont,
struct css_set *cg = link->cg;
struct task_struct *task;
int count = 0;
@@ -74632,15 +74602,19 @@ index 00eb8f7..d7e3244 100644
#ifdef CONFIG_MODULE_UNLOAD
{
diff --git a/kernel/events/core.c b/kernel/events/core.c
-index 9fcb094..fd68c54 100644
+index 9fcb094..8370228 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
-@@ -155,7 +155,11 @@ static struct srcu_struct pmus_srcu;
+@@ -154,8 +154,15 @@ static struct srcu_struct pmus_srcu;
+ * 0 - disallow raw tracepoint access for unpriv
* 1 - disallow cpu events for unpriv
* 2 - disallow kernel profiling for unpriv
++ * 3 - disallow all unpriv perf event use
*/
-int sysctl_perf_event_paranoid __read_mostly = 1;
-+#ifdef CONFIG_GRKERNSEC_HIDESYM
++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN
++int sysctl_perf_event_legitimately_concerned __read_mostly = 3;
++#elif CONFIG_GRKERNSEC_HIDESYM
+int sysctl_perf_event_legitimately_concerned __read_mostly = 2;
+#else
+int sysctl_perf_event_legitimately_concerned __read_mostly = 1;
@@ -74648,7 +74622,7 @@ index 9fcb094..fd68c54 100644
/* Minimum for 512 kiB + 1 user control page */
int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */
-@@ -182,7 +186,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write,
+@@ -182,7 +189,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write,
return 0;
}
@@ -74657,7 +74631,7 @@ index 9fcb094..fd68c54 100644
static void cpu_ctx_sched_out(struct perf_cpu_context *cpuctx,
enum event_type_t event_type);
-@@ -2677,7 +2681,7 @@ static void __perf_event_read(void *info)
+@@ -2677,7 +2684,7 @@ static void __perf_event_read(void *info)
static inline u64 perf_event_count(struct perf_event *event)
{
@@ -74666,7 +74640,7 @@ index 9fcb094..fd68c54 100644
}
static u64 perf_event_read(struct perf_event *event)
-@@ -3007,9 +3011,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
+@@ -3007,9 +3014,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
mutex_lock(&event->child_mutex);
total += perf_event_read(event);
*enabled += event->total_time_enabled +
@@ -74678,7 +74652,7 @@ index 9fcb094..fd68c54 100644
list_for_each_entry(child, &event->child_list, child_list) {
total += perf_event_read(child);
-@@ -3412,10 +3416,10 @@ void perf_event_update_userpage(struct perf_event *event)
+@@ -3412,10 +3419,10 @@ void perf_event_update_userpage(struct perf_event *event)
userpg->offset -= local64_read(&event->hw.prev_count);
userpg->time_enabled = enabled +
@@ -74691,7 +74665,7 @@ index 9fcb094..fd68c54 100644
arch_perf_update_userpage(userpg, now);
-@@ -3886,7 +3890,7 @@ perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size,
+@@ -3886,7 +3893,7 @@ perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size,
/* Data. */
sp = perf_user_stack_pointer(regs);
@@ -74700,7 +74674,7 @@ index 9fcb094..fd68c54 100644
dyn_size = dump_size - rem;
perf_output_skip(handle, rem);
-@@ -3974,11 +3978,11 @@ static void perf_output_read_one(struct perf_output_handle *handle,
+@@ -3974,11 +3981,11 @@ static void perf_output_read_one(struct perf_output_handle *handle,
values[n++] = perf_event_count(event);
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
values[n++] = enabled +
@@ -74714,7 +74688,7 @@ index 9fcb094..fd68c54 100644
}
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(event);
-@@ -4726,12 +4730,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
+@@ -4726,12 +4733,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
* need to add enough zero bytes after the string to handle
* the 64bit alignment we do later.
*/
@@ -74729,7 +74703,7 @@ index 9fcb094..fd68c54 100644
if (IS_ERR(name)) {
name = strncpy(tmp, "//toolong", sizeof(tmp));
goto got_name;
-@@ -6167,7 +6171,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+@@ -6167,7 +6174,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
event->parent = parent_event;
event->ns = get_pid_ns(task_active_pid_ns(current));
@@ -74738,7 +74712,19 @@ index 9fcb094..fd68c54 100644
event->state = PERF_EVENT_STATE_INACTIVE;
-@@ -6795,10 +6799,10 @@ static void sync_child_event(struct perf_event *child_event,
+@@ -6463,6 +6470,11 @@ SYSCALL_DEFINE5(perf_event_open,
+ if (flags & ~PERF_FLAG_ALL)
+ return -EINVAL;
+
++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN
++ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN))
++ return -EACCES;
++#endif
++
+ err = perf_copy_attr(attr_uptr, &attr);
+ if (err)
+ return err;
+@@ -6795,10 +6807,10 @@ static void sync_child_event(struct perf_event *child_event,
/*
* Add back the child's count to the parent's count:
*/
@@ -75791,7 +75777,7 @@ index b2c71c5..7b88d63 100644
seq_printf(m, "%40s %14lu %29s %pS\n",
name, stats->contending_point[i],
diff --git a/kernel/module.c b/kernel/module.c
-index 0925c9a..6b044ac 100644
+index 97f202c..109575f 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -61,6 +61,7 @@
@@ -75956,7 +75942,7 @@ index 0925c9a..6b044ac 100644
set_memory_ro);
}
}
-@@ -1881,16 +1883,19 @@ static void free_module(struct module *mod)
+@@ -1886,16 +1888,19 @@ static void free_module(struct module *mod)
/* This may be NULL, but that's OK */
unset_module_init_ro_nx(mod);
@@ -75979,7 +75965,7 @@ index 0925c9a..6b044ac 100644
#ifdef CONFIG_MPU
update_protections(current->mm);
-@@ -1960,9 +1965,31 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
+@@ -1965,9 +1970,31 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
int ret = 0;
const struct kernel_symbol *ksym;
@@ -76011,7 +75997,7 @@ index 0925c9a..6b044ac 100644
switch (sym[i].st_shndx) {
case SHN_COMMON:
/* We compiled with -fno-common. These are not
-@@ -1983,7 +2010,9 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
+@@ -1988,7 +2015,9 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
ksym = resolve_symbol_wait(mod, info, name);
/* Ok if resolved. */
if (ksym && !IS_ERR(ksym)) {
@@ -76021,7 +76007,7 @@ index 0925c9a..6b044ac 100644
break;
}
-@@ -2002,11 +2031,20 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
+@@ -2007,11 +2036,20 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
secbase = (unsigned long)mod_percpu(mod);
else
secbase = info->sechdrs[sym[i].st_shndx].sh_addr;
@@ -76042,7 +76028,7 @@ index 0925c9a..6b044ac 100644
return ret;
}
-@@ -2090,22 +2128,12 @@ static void layout_sections(struct module *mod, struct load_info *info)
+@@ -2095,22 +2133,12 @@ static void layout_sections(struct module *mod, struct load_info *info)
|| s->sh_entsize != ~0UL
|| strstarts(sname, ".init"))
continue;
@@ -76069,7 +76055,7 @@ index 0925c9a..6b044ac 100644
}
pr_debug("Init section allocation order:\n");
-@@ -2119,23 +2147,13 @@ static void layout_sections(struct module *mod, struct load_info *info)
+@@ -2124,23 +2152,13 @@ static void layout_sections(struct module *mod, struct load_info *info)
|| s->sh_entsize != ~0UL
|| !strstarts(sname, ".init"))
continue;
@@ -76098,7 +76084,7 @@ index 0925c9a..6b044ac 100644
}
}
-@@ -2308,7 +2326,7 @@ static void layout_symtab(struct module *mod, struct load_info *info)
+@@ -2313,7 +2331,7 @@ static void layout_symtab(struct module *mod, struct load_info *info)
/* Put symbol section at end of init part of module. */
symsect->sh_flags |= SHF_ALLOC;
@@ -76107,7 +76093,7 @@ index 0925c9a..6b044ac 100644
info->index.sym) | INIT_OFFSET_MASK;
pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
-@@ -2325,13 +2343,13 @@ static void layout_symtab(struct module *mod, struct load_info *info)
+@@ -2330,13 +2348,13 @@ static void layout_symtab(struct module *mod, struct load_info *info)
}
/* Append room for core symbols at end of core part. */
@@ -76125,7 +76111,7 @@ index 0925c9a..6b044ac 100644
info->index.str) | INIT_OFFSET_MASK;
pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
}
-@@ -2349,12 +2367,14 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
+@@ -2354,12 +2372,14 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
/* Make sure we get permanent strtab: don't use info->strtab. */
mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
@@ -76142,7 +76128,7 @@ index 0925c9a..6b044ac 100644
src = mod->symtab;
for (ndst = i = 0; i < mod->num_symtab; i++) {
if (i == 0 ||
-@@ -2366,6 +2386,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
+@@ -2371,6 +2391,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
}
}
mod->core_num_syms = ndst;
@@ -76151,7 +76137,7 @@ index 0925c9a..6b044ac 100644
}
#else
static inline void layout_symtab(struct module *mod, struct load_info *info)
-@@ -2399,17 +2421,33 @@ void * __weak module_alloc(unsigned long size)
+@@ -2404,17 +2426,33 @@ void * __weak module_alloc(unsigned long size)
return vmalloc_exec(size);
}
@@ -76190,7 +76176,7 @@ index 0925c9a..6b044ac 100644
mutex_unlock(&module_mutex);
}
return ret;
-@@ -2685,8 +2723,14 @@ static struct module *setup_load_info(struct load_info *info, int flags)
+@@ -2690,8 +2728,14 @@ static struct module *setup_load_info(struct load_info *info, int flags)
static int check_modinfo(struct module *mod, struct load_info *info, int flags)
{
const char *modmagic = get_modinfo(info, "vermagic");
@@ -76205,7 +76191,7 @@ index 0925c9a..6b044ac 100644
if (flags & MODULE_INIT_IGNORE_VERMAGIC)
modmagic = NULL;
-@@ -2712,7 +2756,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
+@@ -2717,7 +2761,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
}
/* Set up license info based on the info section */
@@ -76214,7 +76200,7 @@ index 0925c9a..6b044ac 100644
return 0;
}
-@@ -2806,7 +2850,7 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2811,7 +2855,7 @@ static int move_module(struct module *mod, struct load_info *info)
void *ptr;
/* Do the allocs. */
@@ -76223,7 +76209,7 @@ index 0925c9a..6b044ac 100644
/*
* The pointer to this block is stored in the module structure
* which is inside the block. Just mark it as not being a
-@@ -2816,11 +2860,11 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2821,11 +2865,11 @@ static int move_module(struct module *mod, struct load_info *info)
if (!ptr)
return -ENOMEM;
@@ -76239,7 +76225,7 @@ index 0925c9a..6b044ac 100644
/*
* The pointer to this block is stored in the module structure
* which is inside the block. This block doesn't need to be
-@@ -2829,13 +2873,45 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2834,13 +2878,45 @@ static int move_module(struct module *mod, struct load_info *info)
*/
kmemleak_ignore(ptr);
if (!ptr) {
@@ -76289,7 +76275,7 @@ index 0925c9a..6b044ac 100644
/* Transfer each section which specifies SHF_ALLOC */
pr_debug("final section addresses:\n");
-@@ -2846,16 +2922,45 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2851,16 +2927,45 @@ static int move_module(struct module *mod, struct load_info *info)
if (!(shdr->sh_flags & SHF_ALLOC))
continue;
@@ -76342,7 +76328,7 @@ index 0925c9a..6b044ac 100644
pr_debug("\t0x%lx %s\n",
(long)shdr->sh_addr, info->secstrings + shdr->sh_name);
}
-@@ -2912,12 +3017,12 @@ static void flush_module_icache(const struct module *mod)
+@@ -2917,12 +3022,12 @@ static void flush_module_icache(const struct module *mod)
* Do it before processing of module parameters, so the module
* can provide parameter accessor functions of its own.
*/
@@ -76361,7 +76347,7 @@ index 0925c9a..6b044ac 100644
set_fs(old_fs);
}
-@@ -2987,8 +3092,10 @@ out:
+@@ -2992,8 +3097,10 @@ out:
static void module_deallocate(struct module *mod, struct load_info *info)
{
percpu_modfree(mod);
@@ -76374,7 +76360,7 @@ index 0925c9a..6b044ac 100644
}
int __weak module_finalize(const Elf_Ehdr *hdr,
-@@ -3001,7 +3108,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr,
+@@ -3006,7 +3113,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr,
static int post_relocation(struct module *mod, const struct load_info *info)
{
/* Sort exception table now relocations are done. */
@@ -76384,7 +76370,7 @@ index 0925c9a..6b044ac 100644
/* Copy relocated percpu area over. */
percpu_modcopy(mod, (void *)info->sechdrs[info->index.pcpu].sh_addr,
-@@ -3055,16 +3164,16 @@ static int do_init_module(struct module *mod)
+@@ -3060,16 +3169,16 @@ static int do_init_module(struct module *mod)
MODULE_STATE_COMING, mod);
/* Set RO and NX regions for core */
@@ -76409,7 +76395,7 @@ index 0925c9a..6b044ac 100644
do_mod_ctors(mod);
/* Start the module */
-@@ -3126,11 +3235,12 @@ static int do_init_module(struct module *mod)
+@@ -3131,11 +3240,12 @@ static int do_init_module(struct module *mod)
mod->strtab = mod->core_strtab;
#endif
unset_module_init_ro_nx(mod);
@@ -76427,7 +76413,7 @@ index 0925c9a..6b044ac 100644
mutex_unlock(&module_mutex);
wake_up_all(&module_wq);
-@@ -3257,9 +3367,38 @@ static int load_module(struct load_info *info, const char __user *uargs,
+@@ -3262,9 +3372,38 @@ static int load_module(struct load_info *info, const char __user *uargs,
if (err)
goto free_unload;
@@ -76466,7 +76452,7 @@ index 0925c9a..6b044ac 100644
/* Fix up syms, so that st_value is a pointer to location. */
err = simplify_symbols(mod, info);
if (err < 0)
-@@ -3275,13 +3414,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
+@@ -3280,13 +3419,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
flush_module_icache(mod);
@@ -76480,7 +76466,7 @@ index 0925c9a..6b044ac 100644
dynamic_debug_setup(info->debug, info->num_debug);
/* Finally it's fully formed, ready to start executing. */
-@@ -3316,11 +3448,10 @@ static int load_module(struct load_info *info, const char __user *uargs,
+@@ -3321,11 +3453,10 @@ static int load_module(struct load_info *info, const char __user *uargs,
ddebug_cleanup:
dynamic_debug_remove(info->debug);
synchronize_sched();
@@ -76493,7 +76479,7 @@ index 0925c9a..6b044ac 100644
free_unload:
module_unload_free(mod);
unlink_mod:
-@@ -3403,10 +3534,16 @@ static const char *get_ksymbol(struct module *mod,
+@@ -3408,10 +3539,16 @@ static const char *get_ksymbol(struct module *mod,
unsigned long nextval;
/* At worse, next value is at end of module */
@@ -76513,7 +76499,7 @@ index 0925c9a..6b044ac 100644
/* Scan for closest preceding symbol, and next symbol. (ELF
starts real symbols at 1). */
-@@ -3659,7 +3796,7 @@ static int m_show(struct seq_file *m, void *p)
+@@ -3664,7 +3801,7 @@ static int m_show(struct seq_file *m, void *p)
return 0;
seq_printf(m, "%s %u",
@@ -76522,7 +76508,7 @@ index 0925c9a..6b044ac 100644
print_unload_info(m, mod);
/* Informative for users. */
-@@ -3668,7 +3805,7 @@ static int m_show(struct seq_file *m, void *p)
+@@ -3673,7 +3810,7 @@ static int m_show(struct seq_file *m, void *p)
mod->state == MODULE_STATE_COMING ? "Loading":
"Live");
/* Used by oprofile and other similar tools. */
@@ -76531,7 +76517,7 @@ index 0925c9a..6b044ac 100644
/* Taints info */
if (mod->taints)
-@@ -3704,7 +3841,17 @@ static const struct file_operations proc_modules_operations = {
+@@ -3709,7 +3846,17 @@ static const struct file_operations proc_modules_operations = {
static int __init proc_modules_init(void)
{
@@ -76549,7 +76535,7 @@ index 0925c9a..6b044ac 100644
return 0;
}
module_init(proc_modules_init);
-@@ -3765,14 +3912,14 @@ struct module *__module_address(unsigned long addr)
+@@ -3770,14 +3917,14 @@ struct module *__module_address(unsigned long addr)
{
struct module *mod;
@@ -76567,7 +76553,7 @@ index 0925c9a..6b044ac 100644
return mod;
}
return NULL;
-@@ -3807,11 +3954,20 @@ bool is_module_text_address(unsigned long addr)
+@@ -3812,11 +3959,20 @@ bool is_module_text_address(unsigned long addr)
*/
struct module *__module_text_address(unsigned long addr)
{
@@ -78585,7 +78571,7 @@ index 0da73cf..5c2af3c 100644
if (!retval) {
if (old_rlim)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
-index afc1dc6..5e28bbf 100644
+index afc1dc6..f6cf355 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -93,7 +93,6 @@
@@ -78596,6 +78582,34 @@ index afc1dc6..5e28bbf 100644
/* External variables not in a header file. */
extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
+@@ -120,18 +119,18 @@ extern int blk_iopoll_enabled;
+
+ /* Constants used for minimum and maximum */
+ #ifdef CONFIG_LOCKUP_DETECTOR
+-static int sixty = 60;
+-static int neg_one = -1;
++static int sixty __read_only = 60;
+ #endif
+
+-static int zero;
+-static int __maybe_unused one = 1;
+-static int __maybe_unused two = 2;
+-static int __maybe_unused three = 3;
+-static unsigned long one_ul = 1;
+-static int one_hundred = 100;
++static int neg_one __read_only = -1;
++static int zero __read_only = 0;
++static int __maybe_unused one __read_only = 1;
++static int __maybe_unused two __read_only = 2;
++static int __maybe_unused three __read_only = 3;
++static unsigned long one_ul __read_only = 1;
++static int one_hundred __read_only = 100;
+ #ifdef CONFIG_PRINTK
+-static int ten_thousand = 10000;
++static int ten_thousand __read_only = 10000;
+ #endif
+
+ /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
@@ -178,10 +177,8 @@ static int proc_taint(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
#endif
@@ -78691,7 +78705,7 @@ index afc1dc6..5e28bbf 100644
{
.procname = "ngroups_max",
.data = &ngroups_max,
-@@ -1026,8 +1059,8 @@ static struct ctl_table kern_table[] = {
+@@ -1026,10 +1059,17 @@ static struct ctl_table kern_table[] = {
*/
{
.procname = "perf_event_paranoid",
@@ -78700,9 +78714,19 @@ index afc1dc6..5e28bbf 100644
+ .data = &sysctl_perf_event_legitimately_concerned,
+ .maxlen = sizeof(sysctl_perf_event_legitimately_concerned),
.mode = 0644,
- .proc_handler = proc_dointvec,
+- .proc_handler = proc_dointvec,
++ /* go ahead, be a hero */
++ .proc_handler = proc_dointvec_minmax_sysadmin,
++ .extra1 = &neg_one,
++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN
++ .extra2 = &three,
++#else
++ .extra2 = &two,
++#endif
},
-@@ -1283,6 +1316,13 @@ static struct ctl_table vm_table[] = {
+ {
+ .procname = "perf_event_mlock_kb",
+@@ -1283,6 +1323,13 @@ static struct ctl_table vm_table[] = {
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
},
@@ -78716,7 +78740,7 @@ index afc1dc6..5e28bbf 100644
#else
{
.procname = "nr_trim_pages",
-@@ -1733,6 +1773,16 @@ int proc_dostring(struct ctl_table *table, int write,
+@@ -1733,6 +1780,16 @@ int proc_dostring(struct ctl_table *table, int write,
buffer, lenp, ppos);
}
@@ -78733,7 +78757,7 @@ index afc1dc6..5e28bbf 100644
static size_t proc_skip_spaces(char **buf)
{
size_t ret;
-@@ -1838,6 +1888,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
+@@ -1838,6 +1895,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
len = strlen(tmp);
if (len > *size)
len = *size;
@@ -78742,7 +78766,7 @@ index afc1dc6..5e28bbf 100644
if (copy_to_user(*buf, tmp, len))
return -EFAULT;
*size -= len;
-@@ -2002,7 +2054,7 @@ int proc_dointvec(struct ctl_table *table, int write,
+@@ -2002,7 +2061,7 @@ int proc_dointvec(struct ctl_table *table, int write,
static int proc_taint(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -78751,7 +78775,7 @@ index afc1dc6..5e28bbf 100644
unsigned long tmptaint = get_taint();
int err;
-@@ -2030,7 +2082,6 @@ static int proc_taint(struct ctl_table *table, int write,
+@@ -2030,7 +2089,6 @@ static int proc_taint(struct ctl_table *table, int write,
return err;
}
@@ -78759,7 +78783,7 @@ index afc1dc6..5e28bbf 100644
static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
-@@ -2039,7 +2090,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
+@@ -2039,7 +2097,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
}
@@ -78767,7 +78791,7 @@ index afc1dc6..5e28bbf 100644
struct do_proc_dointvec_minmax_conv_param {
int *min;
-@@ -2186,8 +2236,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
+@@ -2186,8 +2243,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
*i = val;
} else {
val = convdiv * (*i) / convmul;
@@ -78780,7 +78804,7 @@ index afc1dc6..5e28bbf 100644
err = proc_put_long(&buffer, &left, val, false);
if (err)
break;
-@@ -2579,6 +2632,12 @@ int proc_dostring(struct ctl_table *table, int write,
+@@ -2579,6 +2639,12 @@ int proc_dostring(struct ctl_table *table, int write,
return -ENOSYS;
}
@@ -78793,7 +78817,7 @@ index afc1dc6..5e28bbf 100644
int proc_dointvec(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
-@@ -2635,5 +2694,6 @@ EXPORT_SYMBOL(proc_dointvec_minmax);
+@@ -2635,5 +2701,6 @@ EXPORT_SYMBOL(proc_dointvec_minmax);
EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
EXPORT_SYMBOL(proc_dostring);
@@ -80367,24 +80391,6 @@ index b32b70c..e512eb0 100644
pkmap_count[last_pkmap_nr] = 1;
set_page_address(page, (void *)vaddr);
-diff --git a/mm/huge_memory.c b/mm/huge_memory.c
-index e2f7f5aa..a4510d4 100644
---- a/mm/huge_memory.c
-+++ b/mm/huge_memory.c
-@@ -2318,7 +2318,12 @@ static void collapse_huge_page(struct mm_struct *mm,
- pte_unmap(pte);
- spin_lock(&mm->page_table_lock);
- BUG_ON(!pmd_none(*pmd));
-- set_pmd_at(mm, address, pmd, _pmd);
-+ /*
-+ * We can only use set_pmd_at when establishing
-+ * hugepmds and never for establishing regular pmds that
-+ * points to regular pagetables. Use pmd_populate for that
-+ */
-+ pmd_populate(mm, pmd, pmd_pgtable(_pmd));
- spin_unlock(&mm->page_table_lock);
- anon_vma_unlock_write(vma->anon_vma);
- goto out;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 1a12f5b..a85b8fc 100644
--- a/mm/hugetlb.c
@@ -81553,7 +81559,7 @@ index 7431001..0f8344e 100644
capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE);
diff --git a/mm/migrate.c b/mm/migrate.c
-index 3bbaf5d..299b0e9 100644
+index 22ed5c1..87c424c 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1382,8 +1382,7 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
@@ -82849,133 +82855,6 @@ index 0dceed8..671951c 100644
vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
-diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
-index be04122..6725ff1 100644
---- a/mm/mmu_notifier.c
-+++ b/mm/mmu_notifier.c
-@@ -40,48 +40,44 @@ void __mmu_notifier_release(struct mm_struct *mm)
- int id;
-
- /*
-- * srcu_read_lock() here will block synchronize_srcu() in
-- * mmu_notifier_unregister() until all registered
-- * ->release() callouts this function makes have
-- * returned.
-+ * SRCU here will block mmu_notifier_unregister until
-+ * ->release returns.
- */
- id = srcu_read_lock(&srcu);
-+ hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist)
-+ /*
-+ * If ->release runs before mmu_notifier_unregister it must be
-+ * handled, as it's the only way for the driver to flush all
-+ * existing sptes and stop the driver from establishing any more
-+ * sptes before all the pages in the mm are freed.
-+ */
-+ if (mn->ops->release)
-+ mn->ops->release(mn, mm);
-+ srcu_read_unlock(&srcu, id);
-+
- spin_lock(&mm->mmu_notifier_mm->lock);
- while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) {
- mn = hlist_entry(mm->mmu_notifier_mm->list.first,
- struct mmu_notifier,
- hlist);
--
- /*
-- * Unlink. This will prevent mmu_notifier_unregister()
-- * from also making the ->release() callout.
-+ * We arrived before mmu_notifier_unregister so
-+ * mmu_notifier_unregister will do nothing other than to wait
-+ * for ->release to finish and for mmu_notifier_unregister to
-+ * return.
- */
- hlist_del_init_rcu(&mn->hlist);
-- spin_unlock(&mm->mmu_notifier_mm->lock);
--
-- /*
-- * Clear sptes. (see 'release' description in mmu_notifier.h)
-- */
-- if (mn->ops->release)
-- mn->ops->release(mn, mm);
--
-- spin_lock(&mm->mmu_notifier_mm->lock);
- }
- spin_unlock(&mm->mmu_notifier_mm->lock);
-
- /*
-- * All callouts to ->release() which we have done are complete.
-- * Allow synchronize_srcu() in mmu_notifier_unregister() to complete
-- */
-- srcu_read_unlock(&srcu, id);
--
-- /*
-- * mmu_notifier_unregister() may have unlinked a notifier and may
-- * still be calling out to it. Additionally, other notifiers
-- * may have been active via vmtruncate() et. al. Block here
-- * to ensure that all notifier callouts for this mm have been
-- * completed and the sptes are really cleaned up before returning
-- * to exit_mmap().
-+ * synchronize_srcu here prevents mmu_notifier_release from returning to
-+ * exit_mmap (which would proceed with freeing all pages in the mm)
-+ * until the ->release method returns, if it was invoked by
-+ * mmu_notifier_unregister.
-+ *
-+ * The mmu_notifier_mm can't go away from under us because one mm_count
-+ * is held by exit_mmap.
- */
- synchronize_srcu(&srcu);
- }
-@@ -292,31 +288,34 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm)
- {
- BUG_ON(atomic_read(&mm->mm_count) <= 0);
-
-- spin_lock(&mm->mmu_notifier_mm->lock);
- if (!hlist_unhashed(&mn->hlist)) {
-+ /*
-+ * SRCU here will force exit_mmap to wait for ->release to
-+ * finish before freeing the pages.
-+ */
- int id;
-
-- /*
-- * Ensure we synchronize up with __mmu_notifier_release().
-- */
- id = srcu_read_lock(&srcu);
--
-- hlist_del_rcu(&mn->hlist);
-- spin_unlock(&mm->mmu_notifier_mm->lock);
--
-- if (mn->ops->release)
-- mn->ops->release(mn, mm);
--
- /*
-- * Allow __mmu_notifier_release() to complete.
-+ * exit_mmap will block in mmu_notifier_release to guarantee
-+ * that ->release is called before freeing the pages.
- */
-+ if (mn->ops->release)
-+ mn->ops->release(mn, mm);
- srcu_read_unlock(&srcu, id);
-- } else
-+
-+ spin_lock(&mm->mmu_notifier_mm->lock);
-+ /*
-+ * Can not use list_del_rcu() since __mmu_notifier_release
-+ * can delete it before we hold the lock.
-+ */
-+ hlist_del_init_rcu(&mn->hlist);
- spin_unlock(&mm->mmu_notifier_mm->lock);
-+ }
-
- /*
-- * Wait for any running method to finish, including ->release() if it
-- * was run by __mmu_notifier_release() instead of us.
-+ * Wait for any running method to finish, of course including
-+ * ->release if it was run by mmu_notifier_relase instead of us.
- */
- synchronize_srcu(&srcu);
-
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 94722a4..07d9926 100644
--- a/mm/mprotect.c
@@ -87120,6 +86999,24 @@ index 960fd29..d55bf64 100644
hdr = register_net_sysctl(&init_net, "net/ipv4", ipv4_table);
if (hdr == NULL)
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index e220207..cdeb839 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3383,8 +3383,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp,
+
+ for (i = 0; i < shi->nr_frags; ++i) {
+ const struct skb_frag_struct *f = &shi->frags[i];
+- struct page *page = skb_frag_page(f);
+- sg_set_page(&sg, page, skb_frag_size(f), f->page_offset);
++ unsigned int offset = f->page_offset;
++ struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT);
++
++ sg_set_page(&sg, page, skb_frag_size(f),
++ offset_in_page(offset));
+ if (crypto_hash_update(desc, &sg, skb_frag_size(f)))
+ return 1;
+ }
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 13b9c08..d33a8d0 100644
--- a/net/ipv4/tcp_input.c
@@ -87527,6 +87424,19 @@ index 95d13c7..791fe2f 100644
.kind = "ip6gretap",
.maxtype = IFLA_GRE_MAX,
.policy = ip6gre_policy,
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 155eccf..851fdae 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1147,7 +1147,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+ if (WARN_ON(np->cork.opt))
+ return -EINVAL;
+
+- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation);
++ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation);
+ if (unlikely(np->cork.opt == NULL))
+ return -ENOBUFS;
+
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index fff83cb..82d49dd 100644
--- a/net/ipv6/ip6_tunnel.c
@@ -88061,6 +87971,19 @@ index 362ba47..66196f4 100644
seq_printf(m, "Max data size: %d\n", self->max_data_size);
seq_printf(m, "Max header size: %d\n", self->max_header_size);
+diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
+index 8c00416..9ea0c93 100644
+--- a/net/irda/irlap_frame.c
++++ b/net/irda/irlap_frame.c
+@@ -544,7 +544,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
+ /*
+ * We now have some discovery info to deliver!
+ */
+- discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
++ discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC);
+ if (!discovery) {
+ IRDA_WARNING("%s: unable to malloc!\n", __func__);
+ return;
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 206ce6d..cfb27cd 100644
--- a/net/iucv/af_iucv.c
@@ -88163,7 +88086,7 @@ index 5672533..6738c93 100644
/* number of interfaces with corresponding FIF_ flags */
int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
-index d51ca9d..042c35f 100644
+index 9cbebc2..14879bb 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -495,7 +495,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
@@ -89949,7 +89872,7 @@ index d5f35f1..da2680b5 100644
task->tk_action = call_reserve;
}
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
-index f8529fc..ce8c643 100644
+index 5356b12..c0f4c29 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -261,9 +261,9 @@ static int rpc_wait_bit_killable(void *word)
@@ -90413,6 +90336,18 @@ index c8717c1..08539f5 100644
err = handler(dev, info, (union iwreq_data *) iwp, extra);
iwp->length += essid_compat;
+diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
+index bcfda89..0cf003d 100644
+--- a/net/xfrm/xfrm_output.c
++++ b/net/xfrm/xfrm_output.c
+@@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
+
+ if (unlikely(x->km.state != XFRM_STATE_VALID)) {
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
++ err = -EINVAL;
+ goto error;
+ }
+
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 167c67d..3f2ae427 100644
--- a/net/xfrm/xfrm_policy.c
diff --git a/main/linux-virt-grsec/ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch b/main/linux-virt-grsec/ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch
deleted file mode 100644
index 7cb0dade7c..0000000000
--- a/main/linux-virt-grsec/ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From patchwork Wed May 22 11:40:47 2013
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-Subject: [ipsec] xfrm: properly handle invalid states as an error
-Date: Wed, 22 May 2013 01:40:47 -0000
-From: =?utf-8?q?Timo_Ter=C3=A4s?= <timo.teras@iki.fi>
-X-Patchwork-Id: 245594
-Message-Id: <1369222847-8542-1-git-send-email-timo.teras@iki.fi>
-To: netdev@vger.kernel.org
-Cc: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>,
- Li RongQing <roy.qing.li@gmail.com>,
- Steffen Klassert <steffen.klassert@secunet.com>
-
-The error exit path needs err explicitly set. Otherwise it
-returns success and the only caller, xfrm_output_resume(),
-would oops in skb_dst(skb)->ops derefence as skb_dst(skb) is
-NULL.
-
-Bug introduced in commit bb65a9cb (xfrm: removes a superfluous
-check and add a statistic).
-
-Signed-off-by: Timo Teräs <timo.teras@iki.fi>
-Cc: Li RongQing <roy.qing.li@gmail.com>
-Cc: Steffen Klassert <steffen.klassert@secunet.com>
-
----
-Should go also to 3.9-stable.
-
- net/xfrm/xfrm_output.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
-index bcfda89..0cf003d 100644
---- a/net/xfrm/xfrm_output.c
-+++ b/net/xfrm/xfrm_output.c
-@@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
-
- if (unlikely(x->km.state != XFRM_STATE_VALID)) {
- XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
-+ err = -EINVAL;
- goto error;
- }
-
diff --git a/main/linux-virt-grsec/ipv4-remove-output-route-check-in-ipv4_mtu.patch b/main/linux-virt-grsec/ipv4-remove-output-route-check-in-ipv4_mtu.patch
deleted file mode 100644
index 241f9b3527..0000000000
--- a/main/linux-virt-grsec/ipv4-remove-output-route-check-in-ipv4_mtu.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 38d523e2948162776903349c89d65f7b9370dadb Mon Sep 17 00:00:00 2001
-From: Steffen Klassert <steffen.klassert@secunet.com>
-Date: Wed, 16 Jan 2013 20:55:01 +0000
-Subject: [PATCH] ipv4: Remove output route check in ipv4_mtu
-MIME-Version: 1.0
-Content-Type: text/plain; charset=utf8
-Content-Transfer-Encoding: 8bit
-
-The output route check was introduced with git commit 261663b0
-(ipv4: Don't use the cached pmtu informations for input routes)
-during times when we cached the pmtu informations on the
-inetpeer. Now the pmtu informations are back in the routes,
-so this check is obsolete. It also had some unwanted side effects,
-as reported by Timo Teras and Lukas Tribus.
-
-Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-Acked-by: Timo Teräs <timo.teras@iki.fi>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/ipv4/route.c | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/net/ipv4/route.c b/net/ipv4/route.c
-index 844a9ef..6e4a89c 100644
---- a/net/ipv4/route.c
-+++ b/net/ipv4/route.c
-@@ -1120,7 +1120,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
- if (!mtu || time_after_eq(jiffies, rt->dst.expires))
- mtu = dst_metric_raw(dst, RTAX_MTU);
-
-- if (mtu && rt_is_output_route(rt))
-+ if (mtu)
- return mtu;
-
- mtu = dst->dev->mtu;
---
-1.7.6.5
-
diff --git a/main/linux-virt-grsec/kernelconfig.x86 b/main/linux-virt-grsec/kernelconfig.x86
index d6858472d1..97a6b06632 100644
--- a/main/linux-virt-grsec/kernelconfig.x86
+++ b/main/linux-virt-grsec/kernelconfig.x86
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/x86 3.9.3 Kernel Configuration
+# Linux/x86 3.9.5 Kernel Configuration
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
@@ -88,7 +88,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
-CONFIG_GENERIC_CMOS_UPDATE=n
+CONFIG_GENERIC_CMOS_UPDATE=y
#
# Timers subsystem
@@ -3448,6 +3448,7 @@ CONFIG_PAX_USERCOPY=y
CONFIG_GRKERNSEC_KMEM=y
# CONFIG_GRKERNSEC_VM86 is not set
# CONFIG_GRKERNSEC_IO is not set
+CONFIG_GRKERNSEC_PERF_HARDEN=y
CONFIG_GRKERNSEC_PROC_MEMMAP=y
# CONFIG_GRKERNSEC_BRUTE is not set
# CONFIG_GRKERNSEC_MODHARDEN is not set
diff --git a/main/linux-virt-grsec/kernelconfig.x86_64 b/main/linux-virt-grsec/kernelconfig.x86_64
index 9992127074..b8026539ea 100644
--- a/main/linux-virt-grsec/kernelconfig.x86_64
+++ b/main/linux-virt-grsec/kernelconfig.x86_64
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/x86 3.9.3 Kernel Configuration
+# Linux/x86 3.9.5 Kernel Configuration
#
CONFIG_64BIT=y
CONFIG_X86_64=y
@@ -89,7 +89,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
-CONFIG_GENERIC_CMOS_UPDATE=n
+CONFIG_GENERIC_CMOS_UPDATE=y
#
# Timers subsystem
@@ -3434,6 +3434,7 @@ CONFIG_PAX_USERCOPY=y
CONFIG_GRKERNSEC_KMEM=y
# CONFIG_GRKERNSEC_IO is not set
CONFIG_GRKERNSEC_JIT_HARDEN=y
+CONFIG_GRKERNSEC_PERF_HARDEN=y
CONFIG_GRKERNSEC_PROC_MEMMAP=y
# CONFIG_GRKERNSEC_BRUTE is not set
# CONFIG_GRKERNSEC_MODHARDEN is not set
diff --git a/main/linux-virt-grsec/leds-leds-gpio-reserve-gpio-before-using-it.patch b/main/linux-virt-grsec/leds-leds-gpio-reserve-gpio-before-using-it.patch
deleted file mode 100644
index f7af3b2a07..0000000000
--- a/main/linux-virt-grsec/leds-leds-gpio-reserve-gpio-before-using-it.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 37e3042c345024aa5e39a1a28a667a00b75fd6ce Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
-Date: Fri, 17 May 2013 09:31:13 +0300
-Subject: [PATCH] leds: leds-gpio: reserve gpio before using it
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit a99d76f (leds: leds-gpio: use gpio_request_one)
-and commit 2d7c22f (leds: leds-gpio: set devm_gpio_request_one()
-flags param correctly) which was a fix of the first one.
-
-The conversion to devm_gpio_request in commit e3b1d44c (leds:
-leds-gpio: use devm_gpio_request_one) is not reverted.
-
-The problem is that gpio_cansleep() and gpio_get_value_cansleep()
-calls can crash if the gpio is not first reserved. Incidentally this
-same bug existed earlier and was fixed similarly in commit d95cbe61
-(leds: Fix potential leds-gpio oops). But the OOPS is real. It happens
-when GPIOs are provided by module which is not yet loaded.
-
-So this fixes the following BUG during my ALIX boot (3.9.2-vanilla):
-
-BUG: unable to handle kernel NULL pointer dereference at 0000004c
-IP: [<c11287d6>] __gpio_cansleep+0xe/0x1a
-*pde = 00000000
-Oops: 0000 [#1] SMP
-Modules linked in: leds_gpio(+) via_rhine mii cs5535_mfd mfd_core
-geode_rng rng_core geode_aes isofs nls_utf8 nls_cp437 vfat fat
-ata_generic pata_amd pata_cs5536 pata_acpi libata ehci_pci ehci_hcd
-ohci_hcd usb_storage usbcore usb_common sd_mod scsi_mod squashfs loop
-Pid: 881, comm: modprobe Not tainted 3.9.2 #1-Alpine
-EIP: 0060:[<c11287d6>] EFLAGS: 00010282 CPU: 0
-EIP is at __gpio_cansleep+0xe/0x1a
-EAX: 00000000 EBX: cf364018 ECX: c132b8b9 EDX: 00000000
-ESI: c13993a4 EDI: c1399370 EBP: cded9dbc ESP: cded9dbc
- DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
-CR0: 8005003b CR2: 0000004c CR3: 0f0c4000 CR4: 00000090
-DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
-DR6: ffff0ff0 DR7: 00000400
-Process modprobe (pid: 881, ti=cded8000 task=cf094aa0 task.ti=cded8000)
-Stack:
- cded9de0 d09471cb 00000000 c1399260 cf364014 00000000 c1399260 c1399254
- d0949014 cded9df4 c118cd59 c1399260 d0949014 d0949014 cded9e08 c118ba47
- c1399260 d0949014 c1399294 cded9e1c c118bb75 cded9e24 d0949014 00000000
-Call Trace:
- [<d09471cb>] gpio_led_probe+0xba/0x203 [leds_gpio]
- [<c118cd59>] platform_drv_probe+0x26/0x48
- [<c118ba47>] driver_probe_device+0x75/0x15c
- [<c118bb75>] __driver_attach+0x47/0x63
- [<c118a727>] bus_for_each_dev+0x3c/0x66
- [<c118b6f9>] driver_attach+0x14/0x16
- [<c118bb2e>] ? driver_probe_device+0x15c/0x15c
- [<c118b3d5>] bus_add_driver+0xbd/0x1bc
- [<d08b4000>] ? 0xd08b3fff
- [<d08b4000>] ? 0xd08b3fff
- [<c118bffc>] driver_register+0x74/0xec
- [<d08b4000>] ? 0xd08b3fff
- [<c118c8e8>] platform_driver_register+0x38/0x3a
- [<d08b400d>] gpio_led_driver_init+0xd/0x1000 [leds_gpio]
- [<c100116c>] do_one_initcall+0x6b/0x10f
- [<d08b4000>] ? 0xd08b3fff
- [<c105e918>] load_module+0x1631/0x1907
- [<c10975d6>] ? insert_vmalloc_vmlist+0x14/0x43
- [<c1098d5b>] ? __vmalloc_node_range+0x13e/0x15f
- [<c105ec50>] sys_init_module+0x62/0x77
- [<c1257888>] syscall_call+0x7/0xb
-EIP: [<c11287d6>] __gpio_cansleep+0xe/0x1a SS:ESP 0068:cded9dbc
-CR2: 000000000000004c
- ---[ end trace 5308fb20d2514822 ]---
-
-Signed-off-by: Timo Teräs <timo.teras@iki.f>
-Cc: Jingoo Han <jg1.han@samsung.com>
-Cc: Sachin Kamat <sachin.kamat@linaro.org>
-Cc: Raphael Assenat <raph@8d.com>
-Cc: Trent Piepho <tpiepho@freescale.com>
-Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
-Cc: Arnaud Patard <arnaud.patard@rtp-net.org>
-Cc: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
----
- drivers/leds/leds-gpio.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
-index a0d931b..b02b679 100644
---- a/drivers/leds/leds-gpio.c
-+++ b/drivers/leds/leds-gpio.c
-@@ -107,6 +107,10 @@ static int create_gpio_led(const struct gpio_led *template,
- return 0;
- }
-
-+ ret = devm_gpio_request(parent, template->gpio, template->name);
-+ if (ret < 0)
-+ return ret;
-+
- led_dat->cdev.name = template->name;
- led_dat->cdev.default_trigger = template->default_trigger;
- led_dat->gpio = template->gpio;
-@@ -126,10 +130,7 @@ static int create_gpio_led(const struct gpio_led *template,
- if (!template->retain_state_suspended)
- led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
-
-- ret = devm_gpio_request_one(parent, template->gpio,
-- (led_dat->active_low ^ state) ?
-- GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
-- template->name);
-+ ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
- if (ret < 0)
- return ret;
-
---
-1.8.2.3
-
-
diff --git a/main/linux-virt-grsec/v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch b/main/linux-virt-grsec/v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
deleted file mode 100644
index 0fdafec17e..0000000000
--- a/main/linux-virt-grsec/v2-net-next-arp-flush-arp-cache-on-IFF_NOARP-change.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From patchwork Tue May 21 10:23:44 2013
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-Subject: [v2,net-next] arp: flush arp cache on IFF_NOARP change
-Date: Tue, 21 May 2013 00:23:44 -0000
-From: =?utf-8?q?Timo_Ter=C3=A4s?= <timo.teras@iki.fi>
-X-Patchwork-Id: 245256
-Message-Id: <1369131824-6318-1-git-send-email-timo.teras@iki.fi>
-To: David Miller <davem@davemloft.net>, netdev@vger.kernel.org, kaber@trash.net
-Cc: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
-
-IFF_NOARP affects what kind of neighbor entries are created
-(nud NOARP or nud INCOMPLETE). If the flag changes, flush the arp
-cache to refresh all entries.
-
-Signed-off-by: Timo Teräs <timo.teras@iki.fi>
-
----
-> This patch makes no sense at all.
->
-> The state bit in ->priv_flags is a boolean stating whether the
-> notified should do something or not.
->
-> But you're setting it to match what IFF_NOARP is.
->
-> You should set it any time IFF_NOARP _changes_, and then clear
-> the bit when the notifier clears the neighbour entries.
-
-IFF_NOARP_CHANGED is set according to "changes = dev->flags ^ old_flags;"
-which reflect the change. But I agree that the clearing out bit was
-misplaced. This is especially true as it seems NETDEV_CHANGE can be
-notified from another place too.
-
-I've updated the if.h comment to state that the bit is valid only during
-NETDEV_CHANGE notifier. And __dev_notify_flags is updated to always clear
-the bit after notifiers are done.
-
- include/uapi/linux/if.h | 2 ++
- net/core/dev.c | 6 +++++-
- net/ipv4/arp.c | 4 ++++
- 3 files changed, 11 insertions(+), 1 deletion(-)
-
-diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
-index 1ec407b..1be8b35 100644
---- a/include/uapi/linux/if.h
-+++ b/include/uapi/linux/if.h
-@@ -83,6 +83,8 @@
- #define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */
- #define IFF_LIVE_ADDR_CHANGE 0x100000 /* device supports hardware address
- * change when it's running */
-+#define IFF_NOARP_CHANGED 0x200000 /* Set during NETDEV_CHANGE notifier
-+ * if IFF_NOARP has changed */
-
-
- #define IF_GET_IFACE 0x0001 /* for querying only */
-diff --git a/net/core/dev.c b/net/core/dev.c
-index 18e9730..ce30761 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -4699,8 +4699,12 @@ void __dev_notify_flags(struct net_device *dev, unsigned int old_flags)
- }
-
- if (dev->flags & IFF_UP &&
-- (changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE)))
-+ (changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE))) {
-+ if (changes & IFF_NOARP)
-+ dev->priv_flags |= IFF_NOARP_CHANGED;
- call_netdevice_notifiers(NETDEV_CHANGE, dev);
-+ dev->priv_flags &= ~IFF_NOARP_CHANGED;
-+ }
- }
-
- /**
-diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
-index 247ec19..375b2f2 100644
---- a/net/ipv4/arp.c
-+++ b/net/ipv4/arp.c
-@@ -1241,6 +1241,10 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event,
- neigh_changeaddr(&arp_tbl, dev);
- rt_cache_flush(dev_net(dev));
- break;
-+ case NETDEV_CHANGE:
-+ if (dev->priv_flags & IFF_NOARP_CHANGED)
-+ neigh_changeaddr(&arp_tbl, dev);
-+ break;
- default:
- break;
- }