All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Florian Westphal <fw@strlen.de>,
	Pablo Neira Ayuso <pablo@netfilter.org>
Subject: [PATCH 3.14 27/29] netfilter: x_tables: check for bogus target offset
Date: Wed, 22 Jun 2016 15:37:35 -0700	[thread overview]
Message-ID: <20160622223532.002760069@linuxfoundation.org> (raw)
In-Reply-To: <20160622223530.496939726@linuxfoundation.org>

3.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Florian Westphal <fw@strlen.de>

commit ce683e5f9d045e5d67d1312a42b359cb2ab2a13c upstream.

We're currently asserting that targetoff + targetsize <= nextoff.

Extend it to also check that targetoff is >= sizeof(xt_entry).
Since this is generic code, add an argument pointing to the start of the
match/target, we can then derive the base structure size from the delta.

We also need the e->elems pointer in a followup change to validate matches.

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 |    4 ++--
 net/ipv4/netfilter/arp_tables.c    |    5 +++--
 net/ipv4/netfilter/ip_tables.c     |    5 +++--
 net/ipv6/netfilter/ip6_tables.c    |    5 +++--
 net/netfilter/x_tables.c           |   17 +++++++++++++++--
 5 files changed, 26 insertions(+), 10 deletions(-)

--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -239,7 +239,7 @@ void xt_unregister_match(struct xt_match
 int xt_register_matches(struct xt_match *match, unsigned int n);
 void xt_unregister_matches(struct xt_match *match, unsigned int n);
 
-int xt_check_entry_offsets(const void *base,
+int xt_check_entry_offsets(const void *base, const char *elems,
 			   unsigned int target_offset,
 			   unsigned int next_offset);
 
@@ -435,7 +435,7 @@ void xt_compat_target_from_user(struct x
 				unsigned int *size);
 int xt_compat_target_to_user(const struct xt_entry_target *t,
 			     void __user **dstptr, unsigned int *size);
-int xt_compat_check_entry_offsets(const void *base,
+int xt_compat_check_entry_offsets(const void *base, const char *elems,
 				  unsigned int target_offset,
 				  unsigned int next_offset);
 
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -582,7 +582,8 @@ static inline int check_entry_size_and_h
 	if (!arp_checkentry(&e->arp))
 		return -EINVAL;
 
-	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
 	if (err)
 		return err;
 
@@ -1244,7 +1245,7 @@ check_compat_entry_size_and_hooks(struct
 	if (!arp_checkentry(&e->arp))
 		return -EINVAL;
 
-	ret = xt_compat_check_entry_offsets(e, e->target_offset,
+	ret = xt_compat_check_entry_offsets(e, e->elems, e->target_offset,
 					    e->next_offset);
 	if (ret)
 		return ret;
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -742,7 +742,8 @@ check_entry_size_and_hooks(struct ipt_en
 	if (!ip_checkentry(&e->ip))
 		return -EINVAL;
 
-	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
 	if (err)
 		return err;
 
@@ -1509,7 +1510,7 @@ check_compat_entry_size_and_hooks(struct
 	if (!ip_checkentry(&e->ip))
 		return -EINVAL;
 
-	ret = xt_compat_check_entry_offsets(e,
+	ret = xt_compat_check_entry_offsets(e, e->elems,
 					    e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -753,7 +753,8 @@ check_entry_size_and_hooks(struct ip6t_e
 	if (!ip6_checkentry(&e->ipv6))
 		return -EINVAL;
 
-	err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+				     e->next_offset);
 	if (err)
 		return err;
 
@@ -1521,7 +1522,7 @@ check_compat_entry_size_and_hooks(struct
 	if (!ip6_checkentry(&e->ipv6))
 		return -EINVAL;
 
-	ret = xt_compat_check_entry_offsets(e,
+	ret = xt_compat_check_entry_offsets(e, e->elems,
 					    e->target_offset, e->next_offset);
 	if (ret)
 		return ret;
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -565,14 +565,17 @@ struct compat_xt_standard_target {
 	compat_uint_t verdict;
 };
 
-/* see xt_check_entry_offsets */
-int xt_compat_check_entry_offsets(const void *base,
+int xt_compat_check_entry_offsets(const void *base, const char *elems,
 				  unsigned int target_offset,
 				  unsigned int next_offset)
 {
+	long size_of_base_struct = elems - (const char *)base;
 	const struct compat_xt_entry_target *t;
 	const char *e = base;
 
+	if (target_offset < size_of_base_struct)
+		return -EINVAL;
+
 	if (target_offset + sizeof(*t) > next_offset)
 		return -EINVAL;
 
@@ -596,12 +599,16 @@ EXPORT_SYMBOL(xt_compat_check_entry_offs
  * xt_check_entry_offsets - validate arp/ip/ip6t_entry
  *
  * @base: pointer to arp/ip/ip6t_entry
+ * @elems: pointer to first xt_entry_match, i.e. ip(6)t_entry->elems
  * @target_offset: the arp/ip/ip6_t->target_offset
  * @next_offset: the arp/ip/ip6_t->next_offset
  *
  * validates that target_offset and next_offset are sane.
  * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
  *
+ * This function does not validate the targets or matches themselves, it
+ * only tests that all the offsets and sizes are correct.
+ *
  * The arp/ip/ip6t_entry structure @base must have passed following tests:
  * - it must point to a valid memory location
  * - base to base + next_offset must be accessible, i.e. not exceed allocated
@@ -610,12 +617,18 @@ EXPORT_SYMBOL(xt_compat_check_entry_offs
  * Return: 0 on success, negative errno on failure.
  */
 int xt_check_entry_offsets(const void *base,
+			   const char *elems,
 			   unsigned int target_offset,
 			   unsigned int next_offset)
 {
+	long size_of_base_struct = elems - (const char *)base;
 	const struct xt_entry_target *t;
 	const char *e = base;
 
+	/* target start is within the ip/ip6/arpt_entry struct */
+	if (target_offset < size_of_base_struct)
+		return -EINVAL;
+
 	if (target_offset + sizeof(*t) > next_offset)
 		return -EINVAL;
 

  parent reply	other threads:[~2016-06-22 22:37 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-22 22:37 [PATCH 3.14 00/29] 3.14.73-stable review Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 01/29] netlink: Fix dump skb leak/double free Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 02/29] sfc: on MC reset, clear PIO buffer linkage in TXQs Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 03/29] tcp: record TLP and ER timer stats in v6 stats Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 05/29] ARM: fix PTRACE_SETVFPREGS on SMP systems Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 06/29] crypto: ccp - Fix AES XTS error for request sizes above 4096 Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 07/29] powerpc: Fix definition of SIAR and SDAR registers Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 08/29] powerpc: Use privileged SPR number for MMCR2 Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 09/29] parisc: Fix pagefault crash in unaligned __get_user() call Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 10/29] ecryptfs: forbid opening files without mmap handler Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 11/29] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 12/29] fix d_walk()/non-delayed __d_free() race Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 13/29] MIPS: Fix 64k page support for 32 bit kernels Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 14/29] powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 15/29] netfilter: x_tables: validate e->target_offset early Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 16/29] netfilter: x_tables: make sure e->next_offset covers remaining blob size Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 17/29] netfilter: x_tables: fix unconditional helper Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 18/29] xfs: fix up backport error in fs/xfs/xfs_inode.c Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 19/29] pipe: limit the per-user amount of pages allocated in pipes Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 20/29] netfilter: x_tables: dont move to non-existent next rule Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 21/29] netfilter: x_tables: validate targets of jumps Greg Kroah-Hartman
2016-06-23  8:54   ` Florian Westphal
2016-06-23  9:13     ` Florian Westphal
2016-06-24  2:46       ` Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 22/29] netfilter: x_tables: add and use xt_check_entry_offsets Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 23/29] netfilter: x_tables: kill check_entry helper Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 24/29] netfilter: x_tables: assert minimum target size Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 25/29] netfilter: x_tables: add compat version of xt_check_entry_offsets Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 26/29] netfilter: x_tables: check standard target size too Greg Kroah-Hartman
2016-06-22 22:37 ` Greg Kroah-Hartman [this message]
2016-06-22 22:37 ` [PATCH 3.14 28/29] netfilter: x_tables: validate all offsets and sizes in a rule Greg Kroah-Hartman
2016-06-22 22:37 ` [PATCH 3.14 29/29] netfilter: x_tables: dont reject valid target size on some architectures Greg Kroah-Hartman
2016-06-23  4:54 ` [PATCH 3.14 00/29] 3.14.73-stable review -rc2 Greg Kroah-Hartman
2016-06-23 19:41   ` Guenter Roeck
2016-06-23 21:54   ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160622223532.002760069@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=fw@strlen.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.