Commit 73cd598df46a73d6f02063f2520df115a9b88aa5

Authored by Patrick McHardy
Committed by David S. Miller
1 parent 30c08c41be

[NETFILTER]: ip_tables: fix compat types

Use compat types and compat iterators when dealing with compat entries for
clarity. This doesn't actually make a difference for ip_tables, but is
needed for ip6_tables and arp_tables.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 47 additions and 29 deletions Side-by-side Diff

include/linux/netfilter_ipv4/ip_tables.h
... ... @@ -236,11 +236,6 @@
236 236 #define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
237 237 XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
238 238  
239   -/* fn returns 0 to continue iteration */
240   -#define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
241   - XT_ENTRY_ITERATE_CONTINUE(struct ipt_entry, entries, size, n, fn, \
242   - ## args)
243   -
244 239 /*
245 240 * Main firewall chains definitions and global var's definitions.
246 241 */
247 242  
... ... @@ -316,7 +311,27 @@
316 311 unsigned char elems[0];
317 312 };
318 313  
  314 +/* Helper functions */
  315 +static inline struct ipt_entry_target *
  316 +compat_ipt_get_target(struct compat_ipt_entry *e)
  317 +{
  318 + return (void *)e + e->target_offset;
  319 +}
  320 +
319 321 #define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s)
  322 +
  323 +/* fn returns 0 to continue iteration */
  324 +#define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \
  325 + XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args)
  326 +
  327 +/* fn returns 0 to continue iteration */
  328 +#define COMPAT_IPT_ENTRY_ITERATE(entries, size, fn, args...) \
  329 + XT_ENTRY_ITERATE(struct compat_ipt_entry, entries, size, fn, ## args)
  330 +
  331 +/* fn returns 0 to continue iteration */
  332 +#define COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
  333 + XT_ENTRY_ITERATE_CONTINUE(struct compat_ipt_entry, entries, size, n, \
  334 + fn, ## args)
320 335  
321 336 #endif /* CONFIG_COMPAT */
322 337 #endif /*__KERNEL__*/
net/ipv4/netfilter/ip_tables.c
... ... @@ -1559,7 +1559,7 @@
1559 1559 }
1560 1560  
1561 1561 static inline int
1562   -compat_release_entry(struct ipt_entry *e, unsigned int *i)
  1562 +compat_release_entry(struct compat_ipt_entry *e, unsigned int *i)
1563 1563 {
1564 1564 struct ipt_entry_target *t;
1565 1565  
1566 1566  
... ... @@ -1567,14 +1567,14 @@
1567 1567 return 1;
1568 1568  
1569 1569 /* Cleanup all matches */
1570   - IPT_MATCH_ITERATE(e, compat_release_match, NULL);
1571   - t = ipt_get_target(e);
  1570 + COMPAT_IPT_MATCH_ITERATE(e, compat_release_match, NULL);
  1571 + t = compat_ipt_get_target(e);
1572 1572 module_put(t->u.kernel.target->me);
1573 1573 return 0;
1574 1574 }
1575 1575  
1576 1576 static inline int
1577   -check_compat_entry_size_and_hooks(struct ipt_entry *e,
  1577 +check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
1578 1578 struct xt_table_info *newinfo,
1579 1579 unsigned int *size,
1580 1580 unsigned char *base,
1581 1581  
1582 1582  
... ... @@ -1603,19 +1603,20 @@
1603 1603 return -EINVAL;
1604 1604 }
1605 1605  
1606   - ret = check_entry(e, name);
  1606 + /* For purposes of check_entry casting the compat entry is fine */
  1607 + ret = check_entry((struct ipt_entry *)e, name);
1607 1608 if (ret)
1608 1609 return ret;
1609 1610  
1610 1611 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1611 1612 entry_offset = (void *)e - (void *)base;
1612 1613 j = 0;
1613   - ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
1614   - e->comefrom, &off, &j);
  1614 + ret = COMPAT_IPT_MATCH_ITERATE(e, compat_find_calc_match, name,
  1615 + &e->ip, e->comefrom, &off, &j);
1615 1616 if (ret != 0)
1616 1617 goto release_matches;
1617 1618  
1618   - t = ipt_get_target(e);
  1619 + t = compat_ipt_get_target(e);
1619 1620 target = try_then_request_module(xt_find_target(AF_INET,
1620 1621 t->u.user.name,
1621 1622 t->u.user.revision),
... ... @@ -1643,7 +1644,7 @@
1643 1644 }
1644 1645  
1645 1646 /* Clear counters and comefrom */
1646   - e->counters = ((struct ipt_counters) { 0, 0 });
  1647 + memset(&e->counters, 0, sizeof(e->counters));
1647 1648 e->comefrom = 0;
1648 1649  
1649 1650 (*i)++;
... ... @@ -1657,7 +1658,7 @@
1657 1658 }
1658 1659  
1659 1660 static int
1660   -compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
  1661 +compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
1661 1662 unsigned int *size, const char *name,
1662 1663 struct xt_table_info *newinfo, unsigned char *base)
1663 1664 {
1664 1665  
1665 1666  
1666 1667  
... ... @@ -1671,15 +1672,17 @@
1671 1672 origsize = *size;
1672 1673 de = (struct ipt_entry *)*dstptr;
1673 1674 memcpy(de, e, sizeof(struct ipt_entry));
  1675 + memcpy(&de->counters, &e->counters, sizeof(e->counters));
1674 1676  
1675   - *dstptr += sizeof(struct compat_ipt_entry);
  1677 + *dstptr += sizeof(struct ipt_entry);
1676 1678 *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1677 1679  
1678   - ret = IPT_MATCH_ITERATE(e, xt_compat_match_from_user, dstptr, size);
  1680 + ret = COMPAT_IPT_MATCH_ITERATE(e, xt_compat_match_from_user,
  1681 + dstptr, size);
1679 1682 if (ret)
1680 1683 return ret;
1681 1684 de->target_offset = e->target_offset - (origsize - *size);
1682   - t = ipt_get_target(e);
  1685 + t = compat_ipt_get_target(e);
1683 1686 target = t->u.kernel.target;
1684 1687 xt_compat_target_from_user(t, dstptr, size);
1685 1688  
... ... @@ -1746,11 +1749,11 @@
1746 1749 j = 0;
1747 1750 xt_compat_lock(AF_INET);
1748 1751 /* Walk through entries, checking offsets. */
1749   - ret = IPT_ENTRY_ITERATE(entry0, total_size,
1750   - check_compat_entry_size_and_hooks,
1751   - info, &size, entry0,
1752   - entry0 + total_size,
1753   - hook_entries, underflows, &j, name);
  1752 + ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size,
  1753 + check_compat_entry_size_and_hooks,
  1754 + info, &size, entry0,
  1755 + entry0 + total_size,
  1756 + hook_entries, underflows, &j, name);
1754 1757 if (ret != 0)
1755 1758 goto out_unlock;
1756 1759  
... ... @@ -1791,9 +1794,9 @@
1791 1794 entry1 = newinfo->entries[raw_smp_processor_id()];
1792 1795 pos = entry1;
1793 1796 size = total_size;
1794   - ret = IPT_ENTRY_ITERATE(entry0, total_size,
1795   - compat_copy_entry_from_user, &pos, &size,
1796   - name, newinfo, entry1);
  1797 + ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size,
  1798 + compat_copy_entry_from_user, &pos, &size,
  1799 + name, newinfo, entry1);
1797 1800 compat_flush_offsets();
1798 1801 xt_compat_unlock(AF_INET);
1799 1802 if (ret)
... ... @@ -1808,8 +1811,8 @@
1808 1811 name, &i);
1809 1812 if (ret) {
1810 1813 j -= i;
1811   - IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i,
1812   - compat_release_entry, &j);
  1814 + COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i,
  1815 + compat_release_entry, &j);
1813 1816 IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
1814 1817 xt_free_table_info(newinfo);
1815 1818 return ret;
... ... @@ -1828,7 +1831,7 @@
1828 1831 free_newinfo:
1829 1832 xt_free_table_info(newinfo);
1830 1833 out:
1831   - IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
  1834 + COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
1832 1835 return ret;
1833 1836 out_unlock:
1834 1837 compat_flush_offsets();