From: Greg Kroah-Hartman Date: Tue, 24 Apr 2018 15:01:49 +0000 (+0200) Subject: 4.16-stable patches X-Git-Tag: v4.16.5~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=09eda51e7d0e3d0689e75c92be2fc7a499c03231;p=thirdparty%2Fkernel%2Fstable-queue.git 4.16-stable patches 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 --- 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 index 00000000000..850aa7de16b --- /dev/null +++ b/queue-4.16/netfilter-compat-prepare-xt_compat_init_offsets-to-return-errors.patch @@ -0,0 +1,171 @@ +From 9782a11efc072faaf91d4aa60e9d23553f918029 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 27 Feb 2018 19:42:34 +0100 +Subject: netfilter: compat: prepare xt_compat_init_offsets to return errors + +From: Florian Westphal + +commit 9782a11efc072faaf91d4aa60e9d23553f918029 upstream. + +should have no impact, function still always returns 0. +This patch is only to ease review. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8fc29e2cd18 --- /dev/null +++ b/queue-4.16/netfilter-compat-reject-huge-allocation-requests.patch @@ -0,0 +1,68 @@ +From 7d7d7e02111e9a4dc9d0658597f528f815d820fd Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 27 Feb 2018 19:42:35 +0100 +Subject: netfilter: compat: reject huge allocation requests + +From: Florian Westphal + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..30f1e2150ab --- /dev/null +++ b/queue-4.16/netfilter-x_tables-add-counters-allocation-wrapper.patch @@ -0,0 +1,91 @@ +From c84ca954ac9fa67a6ce27f91f01e4451c74fd8f6 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 27 Feb 2018 19:42:33 +0100 +Subject: netfilter: x_tables: add counters allocation wrapper + +From: Florian Westphal + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..ab8f7c6d9b3 --- /dev/null +++ b/queue-4.16/netfilter-x_tables-cap-allocations-at-512-mbyte.patch @@ -0,0 +1,40 @@ +From 19926968ea86a286aa6fbea16ee3f2e7442f10f0 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 27 Feb 2018 19:42:31 +0100 +Subject: netfilter: x_tables: cap allocations at 512 mbyte + +From: Florian Westphal + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 = XT_MAX_TABLE_SIZE) + return NULL; + + /* __GFP_NORETRY is not fully supported by kvmalloc but it should diff --git a/queue-4.16/netfilter-x_tables-limit-allocation-requests-for-blob-rule-heads.patch b/queue-4.16/netfilter-x_tables-limit-allocation-requests-for-blob-rule-heads.patch index 593f0440aa2..ee49ed5849d 100644 --- a/queue-4.16/netfilter-x_tables-limit-allocation-requests-for-blob-rule-heads.patch +++ b/queue-4.16/netfilter-x_tables-limit-allocation-requests-for-blob-rule-heads.patch @@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman --- 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) { diff --git a/queue-4.16/series b/queue-4.16/series index 0af23708fd0..ce91c7451ef 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -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