From a18aa31b7774d8b36048e256a02d9d689533fc96 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 12 Dec 2007 10:35:16 -0800 Subject: [NETFILTER]: ip_tables: fix compat copy race When copying entries to user, the kernel makes two passes through the data, first copying all the entries, then fixing up names and counters. On the second pass it copies the kernel and match data from userspace to the kernel again to find the corresponding structures, expecting that kernel pointers contained in the data are still valid. This is obviously broken, fix by avoiding the second pass completely and fixing names and counters while dumping the ruleset, using the kernel-internal data structures. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/x_tables.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'net/netfilter/x_tables.c') diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index d9a3bded0d00..b6160e41eb1c 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -377,7 +377,9 @@ int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr, u_int16_t msize = m->u.user.match_size - off; if (copy_to_user(cm, m, sizeof(*cm)) || - put_user(msize, &cm->u.user.match_size)) + put_user(msize, &cm->u.user.match_size) || + copy_to_user(cm->u.user.name, m->u.kernel.match->name, + strlen(m->u.kernel.match->name) + 1)) return -EFAULT; if (match->compat_to_user) { @@ -468,7 +470,9 @@ int xt_compat_target_to_user(struct xt_entry_target *t, void __user **dstptr, u_int16_t tsize = t->u.user.target_size - off; if (copy_to_user(ct, t, sizeof(*ct)) || - put_user(tsize, &ct->u.user.target_size)) + put_user(tsize, &ct->u.user.target_size) || + copy_to_user(ct->u.user.name, t->u.kernel.target->name, + strlen(t->u.kernel.target->name) + 1)) return -EFAULT; if (target->compat_to_user) { -- cgit v1.2.3