]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Apr 2018 15:01:49 +0000 (17:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Apr 2018 15:01:49 +0000 (17:01 +0200)
added patches:
netfilter-compat-prepare-xt_compat_init_offsets-to-return-errors.patch
netfilter-compat-reject-huge-allocation-requests.patch
netfilter-x_tables-add-counters-allocation-wrapper.patch
netfilter-x_tables-cap-allocations-at-512-mbyte.patch

queue-4.16/netfilter-compat-prepare-xt_compat_init_offsets-to-return-errors.patch [new file with mode: 0644]
queue-4.16/netfilter-compat-reject-huge-allocation-requests.patch [new file with mode: 0644]
queue-4.16/netfilter-x_tables-add-counters-allocation-wrapper.patch [new file with mode: 0644]
queue-4.16/netfilter-x_tables-cap-allocations-at-512-mbyte.patch [new file with mode: 0644]
queue-4.16/netfilter-x_tables-limit-allocation-requests-for-blob-rule-heads.patch
queue-4.16/series

diff --git a/queue-4.16/netfilter-compat-prepare-xt_compat_init_offsets-to-return-errors.patch b/queue-4.16/netfilter-compat-prepare-xt_compat_init_offsets-to-return-errors.patch
new file mode 100644 (file)
index 0000000..850aa7d
--- /dev/null
@@ -0,0 +1,171 @@
+From 9782a11efc072faaf91d4aa60e9d23553f918029 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 27 Feb 2018 19:42:34 +0100
+Subject: netfilter: compat: prepare xt_compat_init_offsets to return errors
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 9782a11efc072faaf91d4aa60e9d23553f918029 upstream.
+
+should have no impact, function still always returns 0.
+This patch is only to ease review.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/netfilter/x_tables.h |    2 +-
+ net/bridge/netfilter/ebtables.c    |   10 ++++++++--
+ net/ipv4/netfilter/arp_tables.c    |   10 +++++++---
+ net/ipv4/netfilter/ip_tables.c     |    8 ++++++--
+ net/ipv6/netfilter/ip6_tables.c    |   10 +++++++---
+ net/netfilter/x_tables.c           |    4 +++-
+ 6 files changed, 32 insertions(+), 12 deletions(-)
+
+--- a/include/linux/netfilter/x_tables.h
++++ b/include/linux/netfilter/x_tables.h
+@@ -510,7 +510,7 @@ void xt_compat_unlock(u_int8_t af);
+ int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta);
+ void xt_compat_flush_offsets(u_int8_t af);
+-void xt_compat_init_offsets(u_int8_t af, unsigned int number);
++int xt_compat_init_offsets(u8 af, unsigned int number);
+ int xt_compat_calc_jump(u_int8_t af, unsigned int offset);
+ int xt_compat_match_offset(const struct xt_match *match);
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1821,10 +1821,14 @@ static int compat_table_info(const struc
+ {
+       unsigned int size = info->entries_size;
+       const void *entries = info->entries;
++      int ret;
+       newinfo->entries_size = size;
+-      xt_compat_init_offsets(NFPROTO_BRIDGE, info->nentries);
++      ret = xt_compat_init_offsets(NFPROTO_BRIDGE, info->nentries);
++      if (ret)
++              return ret;
++
+       return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info,
+                                                       entries, newinfo);
+ }
+@@ -2268,7 +2272,9 @@ static int compat_do_replace(struct net
+       xt_compat_lock(NFPROTO_BRIDGE);
+-      xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries);
++      ret = xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries);
++      if (ret < 0)
++              goto out_unlock;
+       ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state);
+       if (ret < 0)
+               goto out_unlock;
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -781,7 +781,9 @@ static int compat_table_info(const struc
+       memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
+       newinfo->initial_entries = 0;
+       loc_cpu_entry = info->entries;
+-      xt_compat_init_offsets(NFPROTO_ARP, info->number);
++      ret = xt_compat_init_offsets(NFPROTO_ARP, info->number);
++      if (ret)
++              return ret;
+       xt_entry_foreach(iter, loc_cpu_entry, info->size) {
+               ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
+               if (ret != 0)
+@@ -1167,7 +1169,7 @@ static int translate_compat_table(struct
+       struct compat_arpt_entry *iter0;
+       struct arpt_replace repl;
+       unsigned int size;
+-      int ret = 0;
++      int ret;
+       info = *pinfo;
+       entry0 = *pentry0;
+@@ -1176,7 +1178,9 @@ static int translate_compat_table(struct
+       j = 0;
+       xt_compat_lock(NFPROTO_ARP);
+-      xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
++      ret = xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
++      if (ret)
++              goto out_unlock;
+       /* Walk through entries, checking offsets. */
+       xt_entry_foreach(iter0, entry0, compatr->size) {
+               ret = check_compat_entry_size_and_hooks(iter0, info, &size,
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -945,7 +945,9 @@ static int compat_table_info(const struc
+       memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
+       newinfo->initial_entries = 0;
+       loc_cpu_entry = info->entries;
+-      xt_compat_init_offsets(AF_INET, info->number);
++      ret = xt_compat_init_offsets(AF_INET, info->number);
++      if (ret)
++              return ret;
+       xt_entry_foreach(iter, loc_cpu_entry, info->size) {
+               ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
+               if (ret != 0)
+@@ -1418,7 +1420,9 @@ translate_compat_table(struct net *net,
+       j = 0;
+       xt_compat_lock(AF_INET);
+-      xt_compat_init_offsets(AF_INET, compatr->num_entries);
++      ret = xt_compat_init_offsets(AF_INET, compatr->num_entries);
++      if (ret)
++              goto out_unlock;
+       /* Walk through entries, checking offsets. */
+       xt_entry_foreach(iter0, entry0, compatr->size) {
+               ret = check_compat_entry_size_and_hooks(iter0, info, &size,
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -962,7 +962,9 @@ static int compat_table_info(const struc
+       memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
+       newinfo->initial_entries = 0;
+       loc_cpu_entry = info->entries;
+-      xt_compat_init_offsets(AF_INET6, info->number);
++      ret = xt_compat_init_offsets(AF_INET6, info->number);
++      if (ret)
++              return ret;
+       xt_entry_foreach(iter, loc_cpu_entry, info->size) {
+               ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
+               if (ret != 0)
+@@ -1425,7 +1427,7 @@ translate_compat_table(struct net *net,
+       struct compat_ip6t_entry *iter0;
+       struct ip6t_replace repl;
+       unsigned int size;
+-      int ret = 0;
++      int ret;
+       info = *pinfo;
+       entry0 = *pentry0;
+@@ -1434,7 +1436,9 @@ translate_compat_table(struct net *net,
+       j = 0;
+       xt_compat_lock(AF_INET6);
+-      xt_compat_init_offsets(AF_INET6, compatr->num_entries);
++      ret = xt_compat_init_offsets(AF_INET6, compatr->num_entries);
++      if (ret)
++              goto out_unlock;
+       /* Walk through entries, checking offsets. */
+       xt_entry_foreach(iter0, entry0, compatr->size) {
+               ret = check_compat_entry_size_and_hooks(iter0, info, &size,
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -604,10 +604,12 @@ int xt_compat_calc_jump(u_int8_t af, uns
+ }
+ EXPORT_SYMBOL_GPL(xt_compat_calc_jump);
+-void xt_compat_init_offsets(u_int8_t af, unsigned int number)
++int xt_compat_init_offsets(u8 af, unsigned int number)
+ {
+       xt[af].number = number;
+       xt[af].cur = 0;
++
++      return 0;
+ }
+ EXPORT_SYMBOL(xt_compat_init_offsets);
diff --git a/queue-4.16/netfilter-compat-reject-huge-allocation-requests.patch b/queue-4.16/netfilter-compat-reject-huge-allocation-requests.patch
new file mode 100644 (file)
index 0000000..8fc29e2
--- /dev/null
@@ -0,0 +1,68 @@
+From 7d7d7e02111e9a4dc9d0658597f528f815d820fd Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 27 Feb 2018 19:42:35 +0100
+Subject: netfilter: compat: reject huge allocation requests
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 7d7d7e02111e9a4dc9d0658597f528f815d820fd upstream.
+
+no need to bother even trying to allocating huge compat offset arrays,
+such ruleset is rejected later on anyway becaus we refuse to allocate
+overly large rule blobs.
+
+However, compat translation happens before blob allocation, so we should
+add a check there too.
+
+This is supposed to help with fuzzing by avoiding oom-killer.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/x_tables.c |   26 ++++++++++++++++++--------
+ 1 file changed, 18 insertions(+), 8 deletions(-)
+
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -554,14 +554,8 @@ int xt_compat_add_offset(u_int8_t af, un
+ {
+       struct xt_af *xp = &xt[af];
+-      if (!xp->compat_tab) {
+-              if (!xp->number)
+-                      return -EINVAL;
+-              xp->compat_tab = vmalloc(sizeof(struct compat_delta) * xp->number);
+-              if (!xp->compat_tab)
+-                      return -ENOMEM;
+-              xp->cur = 0;
+-      }
++      if (WARN_ON(!xp->compat_tab))
++              return -ENOMEM;
+       if (xp->cur >= xp->number)
+               return -EINVAL;
+@@ -606,6 +600,22 @@ EXPORT_SYMBOL_GPL(xt_compat_calc_jump);
+ int xt_compat_init_offsets(u8 af, unsigned int number)
+ {
++      size_t mem;
++
++      if (!number || number > (INT_MAX / sizeof(struct compat_delta)))
++              return -EINVAL;
++
++      if (WARN_ON(xt[af].compat_tab))
++              return -EINVAL;
++
++      mem = sizeof(struct compat_delta) * number;
++      if (mem > XT_MAX_TABLE_SIZE)
++              return -ENOMEM;
++
++      xt[af].compat_tab = vmalloc(mem);
++      if (!xt[af].compat_tab)
++              return -ENOMEM;
++
+       xt[af].number = number;
+       xt[af].cur = 0;
diff --git a/queue-4.16/netfilter-x_tables-add-counters-allocation-wrapper.patch b/queue-4.16/netfilter-x_tables-add-counters-allocation-wrapper.patch
new file mode 100644 (file)
index 0000000..30f1e21
--- /dev/null
@@ -0,0 +1,91 @@
+From c84ca954ac9fa67a6ce27f91f01e4451c74fd8f6 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 27 Feb 2018 19:42:33 +0100
+Subject: netfilter: x_tables: add counters allocation wrapper
+
+From: Florian Westphal <fw@strlen.de>
+
+commit c84ca954ac9fa67a6ce27f91f01e4451c74fd8f6 upstream.
+
+allows to have size checks in a single spot.
+This is supposed to reduce oom situations when fuzz-testing xtables.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/netfilter/x_tables.h |    1 +
+ net/ipv4/netfilter/arp_tables.c    |    2 +-
+ net/ipv4/netfilter/ip_tables.c     |    2 +-
+ net/ipv6/netfilter/ip6_tables.c    |    2 +-
+ net/netfilter/x_tables.c           |   15 +++++++++++++++
+ 5 files changed, 19 insertions(+), 3 deletions(-)
+
+--- a/include/linux/netfilter/x_tables.h
++++ b/include/linux/netfilter/x_tables.h
+@@ -301,6 +301,7 @@ int xt_data_to_user(void __user *dst, co
+ void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
+                                struct xt_counters_info *info, bool compat);
++struct xt_counters *xt_counters_alloc(unsigned int counters);
+ struct xt_table *xt_register_table(struct net *net,
+                                  const struct xt_table *table,
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -895,7 +895,7 @@ static int __do_replace(struct net *net,
+       struct arpt_entry *iter;
+       ret = 0;
+-      counters = vzalloc(num_counters * sizeof(struct xt_counters));
++      counters = xt_counters_alloc(num_counters);
+       if (!counters) {
+               ret = -ENOMEM;
+               goto out;
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -1057,7 +1057,7 @@ __do_replace(struct net *net, const char
+       struct ipt_entry *iter;
+       ret = 0;
+-      counters = vzalloc(num_counters * sizeof(struct xt_counters));
++      counters = xt_counters_alloc(num_counters);
+       if (!counters) {
+               ret = -ENOMEM;
+               goto out;
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -1075,7 +1075,7 @@ __do_replace(struct net *net, const char
+       struct ip6t_entry *iter;
+       ret = 0;
+-      counters = vzalloc(num_counters * sizeof(struct xt_counters));
++      counters = xt_counters_alloc(num_counters);
+       if (!counters) {
+               ret = -ENOMEM;
+               goto out;
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -1199,6 +1199,21 @@ static int xt_jumpstack_alloc(struct xt_
+       return 0;
+ }
++struct xt_counters *xt_counters_alloc(unsigned int counters)
++{
++      struct xt_counters *mem;
++
++      if (counters == 0 || counters > INT_MAX / sizeof(*mem))
++              return NULL;
++
++      counters *= sizeof(*mem);
++      if (counters > XT_MAX_TABLE_SIZE)
++              return NULL;
++
++      return vzalloc(counters);
++}
++EXPORT_SYMBOL(xt_counters_alloc);
++
+ struct xt_table_info *
+ xt_replace_table(struct xt_table *table,
+             unsigned int num_counters,
diff --git a/queue-4.16/netfilter-x_tables-cap-allocations-at-512-mbyte.patch b/queue-4.16/netfilter-x_tables-cap-allocations-at-512-mbyte.patch
new file mode 100644 (file)
index 0000000..ab8f7c6
--- /dev/null
@@ -0,0 +1,40 @@
+From 19926968ea86a286aa6fbea16ee3f2e7442f10f0 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 27 Feb 2018 19:42:31 +0100
+Subject: netfilter: x_tables: cap allocations at 512 mbyte
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 19926968ea86a286aa6fbea16ee3f2e7442f10f0 upstream.
+
+Arbitrary limit, however, this still allows huge rulesets
+(> 1 million rules).  This helps with automated fuzzer as it prevents
+oom-killer invocation.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/x_tables.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -40,6 +40,7 @@ MODULE_AUTHOR("Harald Welte <laforge@net
+ MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
+ #define XT_PCPU_BLOCK_SIZE 4096
++#define XT_MAX_TABLE_SIZE     (512 * 1024 * 1024)
+ struct compat_delta {
+       unsigned int offset; /* offset in kernel */
+@@ -1029,7 +1030,7 @@ struct xt_table_info *xt_alloc_table_inf
+       struct xt_table_info *info = NULL;
+       size_t sz = sizeof(*info) + size;
+-      if (sz < sizeof(*info))
++      if (sz < sizeof(*info) || sz >= XT_MAX_TABLE_SIZE)
+               return NULL;
+       /* __GFP_NORETRY is not fully supported by kvmalloc but it should
index 593f0440aa2a383d4117166cac9e6dbd5a821518..ee49ed5849d449510c2b7f9dd88c7a918931fb93 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 --- a/net/netfilter/x_tables.c
 +++ b/net/netfilter/x_tables.c
-@@ -805,6 +805,9 @@ EXPORT_SYMBOL(xt_check_entry_offsets);
+@@ -818,6 +818,9 @@ EXPORT_SYMBOL(xt_check_entry_offsets);
   */
  unsigned int *xt_alloc_entry_offsets(unsigned int size)
  {
index 0af23708fd03cb44016068cb30ce34267c1b4bbb..ce91c7451efc79aff0f99444635563cb359b4c81 100644 (file)
@@ -16,6 +16,10 @@ drm-i915-fix-lspcon-tmds-output-buffer-enabling-from-low-power-state.patch
 alarmtimer-init-nanosleep-alarm-timer-on-stack.patch
 mac80211_hwsim-fix-use-after-free-bug-in-hwsim_exit_net.patch
 mm-vmscan-allow-preallocating-memory-for-register_shrinker.patch
+netfilter-x_tables-cap-allocations-at-512-mbyte.patch
+netfilter-x_tables-add-counters-allocation-wrapper.patch
+netfilter-compat-prepare-xt_compat_init_offsets-to-return-errors.patch
+netfilter-compat-reject-huge-allocation-requests.patch
 netfilter-x_tables-limit-allocation-requests-for-blob-rule-heads.patch
 perf-fix-sample_max_stack-maximum-check.patch
 perf-return-proper-values-for-user-stack-errors.patch