netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: netfilter-devel@vger.kernel.org
Cc: Florian Westphal <fw@strlen.de>, Bart De Schuymer <bdschuym@pandora.be>
Subject: [PATCH 08/10] netfilter: ebtables: try native set/getsockopt handlers, too
Date: Thu, 11 Feb 2010 15:12:38 +0100	[thread overview]
Message-ID: <1265897559-10610-9-git-send-email-fw@strlen.de> (raw)
In-Reply-To: <1265897559-10610-1-git-send-email-fw@strlen.de>

ebtables can be compiled to perform userspace-side padding of
structures. In that case, all the structures are already in the
'native' format expected by the kernel.

This tries to determine what format the userspace program is
using.

For most set/getsockopts, this can be done by re-trying the
native handler once the compat_ version returns an error.

In case of EBT_SO_GET_ENTRIES, the native handler is tried first,
it should error out very early when checking the *len argument
(the compat version has to defer this check until after
 iterating over the kernel data set once, to adjust for all
 the structure size differences).

The (useful) error printk is suppressed in this case, as we
will try again in compat mode.

Cc: Bart De Schuymer <bdschuym@pandora.be>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/bridge/netfilter/ebtables.c |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index f173362..0af641f 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1406,7 +1406,7 @@ static int copy_counters_to_user(struct ebt_table *t, struct ebt_counter *oldcou
 
 /* called with ebt_mutex locked */
 static int copy_everything_to_user(struct ebt_table *t, void __user *user,
-   int *len, int cmd)
+   int *len, int cmd, bool compat)
 {
 	struct ebt_replace tmp;
 	struct ebt_counter *oldcounters;
@@ -1426,14 +1426,13 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user,
 		oldcounters = t->table->counters;
 	}
 
-	if (copy_from_user(&tmp, user, sizeof(tmp))) {
-		BUGPRINT("Cfu didn't work\n");
+	if (copy_from_user(&tmp, user, sizeof(tmp)))
 		return -EFAULT;
-	}
 
 	if (*len != sizeof(struct ebt_replace) + entries_size +
 	   (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
-		BUGPRINT("Wrong size\n");
+		if (!compat)
+			BUGPRINT("Wrong size\n");
 		return -EINVAL;
 	}
 
@@ -1526,7 +1525,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 
 	case EBT_SO_GET_ENTRIES:
 	case EBT_SO_GET_INIT_ENTRIES:
-		ret = copy_everything_to_user(t, user, len, cmd);
+		ret = copy_everything_to_user(t, user, len, cmd, false);
 		mutex_unlock(&ebt_mutex);
 		break;
 
@@ -2178,8 +2177,12 @@ static int compat_do_replace(struct net *net, void __user *user, unsigned int le
 	void *entries_tmp;
 
 	ret = compat_copy_ebt_replace_from_user(&tmp, user, len);
-	if (ret)
+	if (ret) {
+		/* try real handler in case userland supplied needed padding */
+		if (do_replace(net, user, len) == 0)
+			ret = 0;
 		return ret;
+	}
 
 	countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids;
 	newinfo = vmalloc(sizeof(*newinfo) + countersize);
@@ -2268,8 +2271,9 @@ static int compat_update_counters(struct net *net, void __user *user, unsigned i
 	if (copy_from_user(&hlp, user, sizeof(hlp)))
 		return -EFAULT;
 
+	/* try real handler in case userland supplied needed padding */
 	if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
-		return -EINVAL;
+		return update_counters(net, user, len);
 
 	return do_update_counters(net, hlp.name, compat_ptr(hlp.counters),
 					hlp.num_counters, user, len);
@@ -2305,9 +2309,10 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, in
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 
+	/* try real handler in case userland supplied needed padding */
 	if ((cmd == EBT_SO_GET_INFO ||
 	     cmd == EBT_SO_GET_INIT_INFO) && *len != sizeof(tmp))
-			return -EINVAL;
+			return do_ebt_get_ctl(sk, cmd, user, len);
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)))
 		return -EFAULT;
@@ -2344,7 +2349,10 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, in
 		break;
 	case EBT_SO_GET_ENTRIES:
 	case EBT_SO_GET_INIT_ENTRIES:
-		ret = compat_copy_everything_to_user(t, user, len, cmd);
+		if (copy_everything_to_user(t, user, len, cmd, true) == 0)
+			ret = 0;
+		else
+			ret = compat_copy_everything_to_user(t, user, len, cmd);
 		break;
 	default:
 		ret = -EINVAL;
-- 
1.6.3.3


  parent reply	other threads:[~2010-02-11 14:12 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-11 14:12 [PATCH v2 0/10] netfilter: ebtables: CONFIG_COMPAT support Florian Westphal
2010-02-11 14:12 ` [PATCH 01/10] netfilter: ebtables: abort if next_offset is too small Florian Westphal
2010-02-15 17:40   ` Patrick McHardy
2010-02-11 14:12 ` [PATCH 02/10] netfilter: ebtables: avoid explicit XT_ALIGN() in match/targets Florian Westphal
2010-02-15 17:40   ` Patrick McHardy
2010-02-11 14:12 ` [PATCH 03/10] netfilter: CONFIG_COMPAT: allow delta to exceed 32767 Florian Westphal
2010-02-15 16:33   ` Patrick McHardy
2010-02-15 16:37     ` Florian Westphal
2010-02-15 17:08       ` Patrick McHardy
2010-02-15 17:40   ` Patrick McHardy
2010-02-11 14:12 ` [PATCH 04/10] netfilter: ebtables: split do_replace into two functions Florian Westphal
2010-02-11 14:12 ` [PATCH 05/10] netfilter: ebtables: split copy_everything_to_user " Florian Westphal
2010-02-11 14:12 ` [PATCH 06/10] netfilter: ebtables: split update_counters " Florian Westphal
2010-02-11 14:12 ` [PATCH 07/10] netfilter: ebtables: add CONFIG_COMPAT support Florian Westphal
2010-02-11 14:12 ` Florian Westphal [this message]
2010-02-11 17:40   ` [PATCH 08/10] netfilter: ebtables: try native set/getsockopt handlers, too Patrick McHardy
2010-02-11 21:50     ` Florian Westphal
2010-02-11 14:12 ` [PATCH 09/10] netfilter: ebt_limit: add CONFIG_COMPAT support Florian Westphal
2010-02-13 13:20 ` [PATCH v2 0/10] netfilter: ebtables: " Bart De Schuymer
2010-02-13 13:31   ` Florian Westphal

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=1265897559-10610-9-git-send-email-fw@strlen.de \
    --to=fw@strlen.de \
    --cc=bdschuym@pandora.be \
    --cc=netfilter-devel@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).