iptables: fix regression with unintended free in need_protomatch
[project/firewall3.git] / iptables.c
index e7e8b597c0dd948dbe327e100f1c54710b83bc12..d03d1dd2933e8000712a0696c4e0d60fa6142347 100644 (file)
@@ -709,12 +709,18 @@ init_match(struct fw3_ipt_rule *r, struct xtables_match *m, bool no_clone)
 static bool
 need_protomatch(struct fw3_ipt_rule *r, const char *pname)
 {
+       struct xtables_match *match;
+
        if (!pname)
                return false;
 
-       if (!xtables_find_match(pname, XTF_DONT_LOAD, NULL))
+       match = xtables_find_match(pname, XTF_DONT_LOAD, NULL);
+       if (!match)
                return true;
 
+       /* Free any kind of clone from xtables_find_match */
+       if (match == match->next)
+               free(match);
        return !r->protocol_loaded;
 }
 
@@ -1022,7 +1028,7 @@ fw3_ipt_rule_icmptype(struct fw3_ipt_rule *r, struct fw3_icmptype *icmp)
 #endif
        {
                if (icmp->code_min == 0 && icmp->code_max == 0xFF)
-                       sprintf(buf, "%u", icmp->type);
+                       snprintf(buf, sizeof(buf), "%u", icmp->type);
                else
                        snprintf(buf, sizeof(buf), "%u/%u", icmp->type, icmp->code_min);
 
@@ -1208,7 +1214,7 @@ fw3_ipt_rule_time(struct fw3_ipt_rule *r, struct fw3_time *time)
                                        rem--;
                                }
 
-                               p += snprintf(p, rem, "%u", i);
+                               len = snprintf(p, rem, "%u", i);
 
                                if (len < 0 || len >= rem)
                                        break;