Patch "netfilter: x_tables: validate e->target_offset early" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
netfilter: x_tables: validate e->target_offset early
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
netfilter-x_tables-validate-e-target_offset-early.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
bdf533de6968e9686df777dc178486f600c6e617Mon Sep 17 00:00:00 2001
From: Florian Westphal <[email protected]>
Date: Tue, 22 Mar 2016 18:02:49 +0100
Subject: netfilter: x_tables: validate e->target_offset early
From: Florian Westphal <[email protected]>
commit bdf533de6968e9686df777dc178486f600c6e617 upstream.
We should check that e->target_offset is sane before mark_source_chains gets called since it will fetch the target entry for loop detection.
--- net/ipv4/netfilter/arp_tables.c | 17 ++++++++--------- net/ipv4/netfilter/ip_tables.c | 17 ++++++++--------- net/ipv6/netfilter/ip6_tables.c | 17 ++++++++--------- 3 files changed, 24 insertions(+), 27 deletions(-)
net/ipv4/netfilter/arp_tables.c +8 -9
@@ -474,14 +474,12 @@ next:return 1 ; } -static inline int check_entry (const struct arpt_entry *e,const char *name) +static inline int check_entry (const struct arpt_entry *e) {const struct xt_entry_target *t; -if (!arp_checkentry (&e->arp)) { -duprintf ("arp_tables: arp check failed %p %s.\n" , e, name); +if (!arp_checkentry (&e->arp))return -EINVAL ; - }if (e->target_offset +sizeof (struct xt_entry_target ) > e->next_offset)return -EINVAL ;
@@ -522,10 +520,6 @@ find_check_entry(struct arpt_entry *e, cstruct xt_target *target;int ret; - ret =check_entry (e, name); -if (ret) -return ret; - e->counters.pcnt =xt_percpu_counter_alloc ();if (IS_ERR_VALUE (e->counters.pcnt))return -ENOMEM ;
@@ -576,6 +570,7 @@ static inline int check_entry_size_and_h unsigned int valid_hooks) {unsigned int h; +int err;if ((unsigned long )e % __alignof__(struct arpt_entry ) !=0 || (unsigned char *)e +sizeof (struct arpt_entry ) >= limit) {
@@ -590,6 +585,10 @@ static inline int check_entry_size_and_hreturn -EINVAL ; } + err =check_entry (e); +if (err) +return err; +/* Check hooks & underflows */ for (h =0 ; h <NF_ARP_NUMHOOKS ; h++) {if (!(valid_hooks & (1 << h)))
@@ -1246,7 +1245,7 @@ check_compat_entry_size_and_hooks(struct }/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct arpt_entry *)e, name); + ret =check_entry ((struct arpt_entry *)e);if (ret)return ret;
net/ipv4/netfilter/ip_tables.c +8 -9
@@ -569,14 +569,12 @@ static void cleanup_match(struct xt_entr }static int -check_entry (const struct ipt_entry *e,const char *name) +check_entry (const struct ipt_entry *e) {const struct xt_entry_target *t; -if (!ip_checkentry (&e->ip)) { -duprintf ("ip check failed %p %s.\n" , e, name); +if (!ip_checkentry (&e->ip))return -EINVAL ; - }if (e->target_offset +sizeof (struct xt_entry_target ) > e->next_offset)
@@ -666,10 +664,6 @@ find_check_entry(struct ipt_entry *e, ststruct xt_mtchk_param mtpar;struct xt_entry_match *ematch; - ret =check_entry (e, name); -if (ret) -return ret; - e->counters.pcnt =xt_percpu_counter_alloc ();if (IS_ERR_VALUE (e->counters.pcnt))return -ENOMEM ;
@@ -741,6 +735,7 @@ check_entry_size_and_hooks(struct ipt_en unsigned int valid_hooks) {unsigned int h; +int err;if ((unsigned long )e % __alignof__(struct ipt_entry ) !=0 || (unsigned char *)e +sizeof (struct ipt_entry ) >= limit) {
@@ -755,6 +750,10 @@ check_entry_size_and_hooks(struct ipt_enreturn -EINVAL ; } + err =check_entry (e); +if (err) +return err; +/* Check hooks & underflows */ for (h =0 ; h <NF_INET_NUMHOOKS ; h++) {if (!(valid_hooks & (1 << h)))
@@ -1506,7 +1505,7 @@ check_compat_entry_size_and_hooks(struct }/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct ipt_entry *)e, name); + ret =check_entry ((struct ipt_entry *)e);if (ret)return ret;
net/ipv6/netfilter/ip6_tables.c +8 -9
@@ -581,14 +581,12 @@ static void cleanup_match(struct xt_entr }static int -check_entry (const struct ip6t_entry *e,const char *name) +check_entry (const struct ip6t_entry *e) {const struct xt_entry_target *t; -if (!ip6_checkentry (&e->ipv6)) { -duprintf ("ip_tables: ip check failed %p %s.\n" , e, name); +if (!ip6_checkentry (&e->ipv6))return -EINVAL ; - }if (e->target_offset +sizeof (struct xt_entry_target ) > e->next_offset)
@@ -679,10 +677,6 @@ find_check_entry(struct ip6t_entry *e, sstruct xt_mtchk_param mtpar;struct xt_entry_match *ematch; - ret =check_entry (e, name); -if (ret) -return ret; - e->counters.pcnt =xt_percpu_counter_alloc ();if (IS_ERR_VALUE (e->counters.pcnt))return -ENOMEM ;
@@ -753,6 +747,7 @@ check_entry_size_and_hooks(struct ip6t_e unsigned int valid_hooks) {unsigned int h; +int err;if ((unsigned long )e % __alignof__(struct ip6t_entry ) !=0 || (unsigned char *)e +sizeof (struct ip6t_entry ) >= limit) {
@@ -767,6 +762,10 @@ check_entry_size_and_hooks(struct ip6t_ereturn -EINVAL ; } + err =check_entry (e); +if (err) +return err; +/* Check hooks & underflows */ for (h =0 ; h <NF_INET_NUMHOOKS ; h++) {if (!(valid_hooks & (1 << h)))
@@ -1518,7 +1517,7 @@ check_compat_entry_size_and_hooks(struct }/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct ip6t_entry *)e, name); + ret =check_entry ((struct ip6t_entry *)e);if (ret)return ret;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/netfilter-x_tables-validate-e-target_offset-early.patch queue-4.4/netfilter-x_tables-make-sure-e-next_offset-covers-remaining-blob-size.patch queue-4.4/netfilter-x_tables-fix-unconditional-helper.patch