610-netfilter_match_bypass_default_checks.patch 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. --- a/include/uapi/linux/netfilter_ipv4/ip_tables.h
  2. +++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h
  3. @@ -87,6 +87,7 @@ struct ipt_ip {
  4. #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
  5. #define IPT_F_GOTO 0x02 /* Set if jump is a goto */
  6. #define IPT_F_MASK 0x03 /* All possible flag bits mask. */
  7. +#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */
  8. /* Values for "inv" field in struct ipt_ip. */
  9. #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
  10. --- a/net/ipv4/netfilter/ip_tables.c
  11. +++ b/net/ipv4/netfilter/ip_tables.c
  12. @@ -82,6 +82,9 @@ ip_packet_match(const struct iphdr *ip,
  13. #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
  14. + if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
  15. + return true;
  16. +
  17. if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
  18. IPT_INV_SRCIP) ||
  19. FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
  20. @@ -135,6 +138,29 @@ ip_packet_match(const struct iphdr *ip,
  21. return true;
  22. }
  23. +static void
  24. +ip_checkdefault(struct ipt_ip *ip)
  25. +{
  26. + static const char iface_mask[IFNAMSIZ] = {};
  27. +
  28. + if (ip->invflags || ip->flags & IPT_F_FRAG)
  29. + return;
  30. +
  31. + if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
  32. + return;
  33. +
  34. + if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
  35. + return;
  36. +
  37. + if (ip->smsk.s_addr || ip->dmsk.s_addr)
  38. + return;
  39. +
  40. + if (ip->proto)
  41. + return;
  42. +
  43. + ip->flags |= IPT_F_NO_DEF_MATCH;
  44. +}
  45. +
  46. static bool
  47. ip_checkentry(const struct ipt_ip *ip)
  48. {
  49. @@ -953,6 +979,7 @@ copy_entries_to_user(unsigned int total_
  50. const struct xt_table_info *private = table->private;
  51. int ret = 0;
  52. const void *loc_cpu_entry;
  53. + u8 flags;
  54. counters = alloc_counters(table);
  55. if (IS_ERR(counters))
  56. @@ -979,6 +1006,14 @@ copy_entries_to_user(unsigned int total_
  57. ret = -EFAULT;
  58. goto free_counters;
  59. }
  60. +
  61. + flags = e->ip.flags & IPT_F_MASK;
  62. + if (copy_to_user(userptr + off
  63. + + offsetof(struct ipt_entry, ip.flags),
  64. + &flags, sizeof(flags)) != 0) {
  65. + ret = -EFAULT;
  66. + goto free_counters;
  67. + }
  68. for (i = sizeof(struct ipt_entry);
  69. i < e->target_offset;