projects
/
project
/
firewall3.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
iptables: fix regression with unintended free in need_protomatch
[project/firewall3.git]
/
iptables.c
diff --git
a/iptables.c
b/iptables.c
index 7ad1d2247ebf17a6f7c7ff54f3f6609e525e6978..d03d1dd2933e8000712a0696c4e0d60fa6142347 100644
(file)
--- a/
iptables.c
+++ b/
iptables.c
@@
-141,12
+141,11
@@
void
get_kernel_version(void)
{
static struct utsname uts;
get_kernel_version(void)
{
static struct utsname uts;
- int x =
0
, y = 0, z = 0;
+ int x =
3
, y = 0, z = 0;
- if (uname(&uts)
=
= -1)
- s
printf(uts.release, "3.0.0"
);
+ if (uname(&uts)
!
= -1)
+ s
scanf(uts.release, "%d.%d.%d", &x, &y, &z
);
- sscanf(uts.release, "%d.%d.%d", &x, &y, &z);
kernel_version = 0x10000 * x + 0x100 * y + z;
}
kernel_version = 0x10000 * x + 0x100 * y + z;
}
@@
-491,22
+490,15
@@
is_chain(struct fw3_ipt_handle *h, const char *name)
void
fw3_ipt_create_chain(struct fw3_ipt_handle *h, bool ignore_existing,
void
fw3_ipt_create_chain(struct fw3_ipt_handle *h, bool ignore_existing,
- const char *
fmt, ...
)
+ const char *
chain
)
{
{
- char buf[32];
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
- va_end(ap);
-
- if (ignore_existing && is_chain(h, buf))
+ if (ignore_existing && is_chain(h, chain))
return;
if (fw3_pr_debug)
return;
if (fw3_pr_debug)
- debug(h, "-N %s\n",
buf
);
+ debug(h, "-N %s\n",
chain
);
- iptc_create_chain(
buf
, h->handle);
+ iptc_create_chain(
chain
, h->handle);
}
void
}
void
@@
-717,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)
{
static bool
need_protomatch(struct fw3_ipt_rule *r, const char *pname)
{
+ struct xtables_match *match;
+
if (!pname)
return false;
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;
return true;
+ /* Free any kind of clone from xtables_find_match */
+ if (match == match->next)
+ free(match);
return !r->protocol_loaded;
}
return !r->protocol_loaded;
}
@@
-952,7
+950,7
@@
void
fw3_ipt_rule_sport_dport(struct fw3_ipt_rule *r,
struct fw3_port *sp, struct fw3_port *dp)
{
fw3_ipt_rule_sport_dport(struct fw3_ipt_rule *r,
struct fw3_port *sp, struct fw3_port *dp)
{
- char buf[sizeof("65535:65535
\0
")];
+ char buf[sizeof("65535:65535")];
if ((!sp || !sp->set) && (!dp || !dp->set))
return;
if ((!sp || !sp->set) && (!dp || !dp->set))
return;
@@
-963,7
+961,7
@@
fw3_ipt_rule_sport_dport(struct fw3_ipt_rule *r,
if (sp && sp->set)
{
if (sp->port_min == sp->port_max)
if (sp && sp->set)
{
if (sp->port_min == sp->port_max)
- s
printf(buf
, "%u", sp->port_min);
+ s
nprintf(buf, sizeof(buf)
, "%u", sp->port_min);
else
snprintf(buf, sizeof(buf), "%u:%u", sp->port_min, sp->port_max);
else
snprintf(buf, sizeof(buf), "%u:%u", sp->port_min, sp->port_max);
@@
-973,7
+971,7
@@
fw3_ipt_rule_sport_dport(struct fw3_ipt_rule *r,
if (dp && dp->set)
{
if (dp->port_min == dp->port_max)
if (dp && dp->set)
{
if (dp->port_min == dp->port_max)
- s
printf(buf
, "%u", dp->port_min);
+ s
nprintf(buf, sizeof(buf)
, "%u", dp->port_min);
else
snprintf(buf, sizeof(buf), "%u:%u", dp->port_min, dp->port_max);
else
snprintf(buf, sizeof(buf), "%u:%u", dp->port_min, dp->port_max);
@@
-984,9
+982,10
@@
fw3_ipt_rule_sport_dport(struct fw3_ipt_rule *r,
void
fw3_ipt_rule_device(struct fw3_ipt_rule *r, const char *device, bool out)
{
void
fw3_ipt_rule_device(struct fw3_ipt_rule *r, const char *device, bool out)
{
+ struct fw3_device dev = { .any = false };
+
if (device) {
if (device) {
- struct fw3_device dev = { .any = false };
- strncpy(dev.name, device, sizeof(dev.name) - 1);
+ snprintf(dev.name, sizeof(dev.name), "%s", device);
fw3_ipt_rule_in_out(r, (out) ? NULL : &dev, (out) ? &dev : NULL);
}
}
fw3_ipt_rule_in_out(r, (out) ? NULL : &dev, (out) ? &dev : NULL);
}
}
@@
-994,14
+993,14
@@
fw3_ipt_rule_device(struct fw3_ipt_rule *r, const char *device, bool out)
void
fw3_ipt_rule_mac(struct fw3_ipt_rule *r, struct fw3_mac *mac)
{
void
fw3_ipt_rule_mac(struct fw3_ipt_rule *r, struct fw3_mac *mac)
{
- char buf[sizeof("ff:ff:ff:ff:ff:ff
\0
")];
+ char buf[sizeof("ff:ff:ff:ff:ff:ff")];
uint8_t *addr = mac->mac.ether_addr_octet;
if (!mac)
return;
uint8_t *addr = mac->mac.ether_addr_octet;
if (!mac)
return;
- s
printf(buf
, "%02x:%02x:%02x:%02x:%02x:%02x",
- addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+ s
nprintf(buf, sizeof(buf)
, "%02x:%02x:%02x:%02x:%02x:%02x",
+
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
fw3_ipt_rule_addarg(r, false, "-m", "mac");
fw3_ipt_rule_addarg(r, mac->invert, "--mac-source", buf);
fw3_ipt_rule_addarg(r, false, "-m", "mac");
fw3_ipt_rule_addarg(r, mac->invert, "--mac-source", buf);
@@
-1010,7
+1009,7
@@
fw3_ipt_rule_mac(struct fw3_ipt_rule *r, struct fw3_mac *mac)
void
fw3_ipt_rule_icmptype(struct fw3_ipt_rule *r, struct fw3_icmptype *icmp)
{
void
fw3_ipt_rule_icmptype(struct fw3_ipt_rule *r, struct fw3_icmptype *icmp)
{
- char buf[sizeof("255/255
\0
")];
+ char buf[sizeof("255/255")];
if (!icmp)
return;
if (!icmp)
return;
@@
-1019,7
+1018,7
@@
fw3_ipt_rule_icmptype(struct fw3_ipt_rule *r, struct fw3_icmptype *icmp)
if (r->h->family == FW3_FAMILY_V6)
{
if (icmp->code6_min == 0 && icmp->code6_max == 0xFF)
if (r->h->family == FW3_FAMILY_V6)
{
if (icmp->code6_min == 0 && icmp->code6_max == 0xFF)
- s
printf(buf
, "%u", icmp->type6);
+ s
nprintf(buf, sizeof(buf)
, "%u", icmp->type6);
else
snprintf(buf, sizeof(buf), "%u/%u", icmp->type6, icmp->code6_min);
else
snprintf(buf, sizeof(buf), "%u/%u", icmp->type6, icmp->code6_min);
@@
-1029,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)
#endif
{
if (icmp->code_min == 0 && icmp->code_max == 0xFF)
- s
printf(buf
, "%u", icmp->type);
+ s
nprintf(buf, sizeof(buf)
, "%u", icmp->type);
else
snprintf(buf, sizeof(buf), "%u/%u", icmp->type, icmp->code_min);
else
snprintf(buf, sizeof(buf), "%u/%u", icmp->type, icmp->code_min);
@@
-1040,19
+1039,19
@@
fw3_ipt_rule_icmptype(struct fw3_ipt_rule *r, struct fw3_icmptype *icmp)
void
fw3_ipt_rule_limit(struct fw3_ipt_rule *r, struct fw3_limit *limit)
{
void
fw3_ipt_rule_limit(struct fw3_ipt_rule *r, struct fw3_limit *limit)
{
- char buf[sizeof("-4294967296/second
\0
")];
+ char buf[sizeof("-4294967296/second")];
if (!limit || limit->rate <= 0)
return;
fw3_ipt_rule_addarg(r, false, "-m", "limit");
if (!limit || limit->rate <= 0)
return;
fw3_ipt_rule_addarg(r, false, "-m", "limit");
- s
printf(buf
, "%u/%s", limit->rate, fw3_limit_units[limit->unit]);
+ s
nprintf(buf, sizeof(buf)
, "%u/%s", limit->rate, fw3_limit_units[limit->unit]);
fw3_ipt_rule_addarg(r, limit->invert, "--limit", buf);
if (limit->burst > 0)
{
fw3_ipt_rule_addarg(r, limit->invert, "--limit", buf);
if (limit->burst > 0)
{
- s
printf(buf
, "%u", limit->burst);
+ s
nprintf(buf, sizeof(buf)
, "%u", limit->burst);
fw3_ipt_rule_addarg(r, limit->invert, "--limit-burst", buf);
}
}
fw3_ipt_rule_addarg(r, limit->invert, "--limit-burst", buf);
}
}
@@
-1060,9
+1059,10
@@
fw3_ipt_rule_limit(struct fw3_ipt_rule *r, struct fw3_limit *limit)
void
fw3_ipt_rule_ipset(struct fw3_ipt_rule *r, struct fw3_setmatch *match)
{
void
fw3_ipt_rule_ipset(struct fw3_ipt_rule *r, struct fw3_setmatch *match)
{
- char buf[sizeof("dst,dst,dst
\0
")];
+ char buf[sizeof("dst,dst,dst")];
char *p = buf;
char *p = buf;
- int i = 0;
+ int i = 0, len;
+ size_t rem = sizeof(buf);
struct fw3_ipset *set;
struct fw3_ipset_datatype *type;
struct fw3_ipset *set;
struct fw3_ipset_datatype *type;
@@
-1076,10
+1076,23
@@
fw3_ipt_rule_ipset(struct fw3_ipt_rule *r, struct fw3_setmatch *match)
if (i >= 3)
break;
if (i >= 3)
break;
- if (p > buf)
+ if (p > buf) {
+ if (rem <= 1)
+ break;
+
*p++ = ',';
*p++ = ',';
+ *p = 0;
+ rem--;
+ }
+
+ len = snprintf(p, rem, "%s", match->dir[i] ? match->dir[i] : type->dir);
+
+ if (len < 0 || len >= rem)
+ break;
+
+ rem -= len;
+ p += len;
- p += sprintf(p, "%s", match->dir[i] ? match->dir[i] : type->dir);
i++;
}
i++;
}
@@
-1104,15
+1117,17
@@
fw3_ipt_rule_helper(struct fw3_ipt_rule *r, struct fw3_cthelpermatch *match)
void
fw3_ipt_rule_time(struct fw3_ipt_rule *r, struct fw3_time *time)
{
void
fw3_ipt_rule_time(struct fw3_ipt_rule *r, struct fw3_time *time)
{
- int i;
+ int i
, len
;
struct tm empty = { 0 };
struct tm empty = { 0 };
- char buf[84]; /* sizeof("1,2,3,...,30,31
\0
") */
+ char buf[84]; /* sizeof("1,2,3,...,30,31") */
char *p;
bool d1 = memcmp(&time->datestart, &empty, sizeof(empty));
bool d2 = memcmp(&time->datestop, &empty, sizeof(empty));
char *p;
bool d1 = memcmp(&time->datestart, &empty, sizeof(empty));
bool d2 = memcmp(&time->datestop, &empty, sizeof(empty));
+ size_t rem;
+
if (!d1 && !d2 && !time->timestart && !time->timestop &&
!(time->monthdays & 0xFFFFFFFE) && !(time->weekdays & 0xFE))
{
if (!d1 && !d2 && !time->timestart && !time->timestop &&
!(time->monthdays & 0xFFFFFFFE) && !(time->weekdays & 0xFE))
{
@@
-1138,7
+1153,7
@@
fw3_ipt_rule_time(struct fw3_ipt_rule *r, struct fw3_time *time)
if (time->timestart)
{
if (time->timestart)
{
- s
printf(buf
, "%02d:%02d:%02d",
+ s
nprintf(buf, sizeof(buf)
, "%02d:%02d:%02d",
time->timestart / 3600,
time->timestart % 3600 / 60,
time->timestart % 60);
time->timestart / 3600,
time->timestart % 3600 / 60,
time->timestart % 60);
@@
-1148,7
+1163,7
@@
fw3_ipt_rule_time(struct fw3_ipt_rule *r, struct fw3_time *time)
if (time->timestop)
{
if (time->timestop)
{
- s
printf(buf
, "%02d:%02d:%02d",
+ s
nprintf(buf, sizeof(buf)
, "%02d:%02d:%02d",
time->timestop / 3600,
time->timestop % 3600 / 60,
time->timestop % 60);
time->timestop / 3600,
time->timestop % 3600 / 60,
time->timestop % 60);
@@
-1158,14
+1173,26
@@
fw3_ipt_rule_time(struct fw3_ipt_rule *r, struct fw3_time *time)
if (time->monthdays & 0xFFFFFFFE)
{
if (time->monthdays & 0xFFFFFFFE)
{
- for (i = 1, p = buf; i < 32; i++)
+ for (i = 1, p = buf
, rem = sizeof(buf)
; i < 32; i++)
{
if (fw3_hasbit(time->monthdays, i))
{
{
if (fw3_hasbit(time->monthdays, i))
{
- if (p > buf)
+ if (p > buf) {
+ if (rem <= 1)
+ break;
+
*p++ = ',';
*p++ = ',';
+ *p = 0;
+ rem--;
+ }
+
+ len = snprintf(p, rem, "%u", i);
+
+ if (len < 0 || len >= rem)
+ break;
- p += sprintf(p, "%u", i);
+ rem -= len;
+ p += len;
}
}
}
}
@@
-1174,14
+1201,26
@@
fw3_ipt_rule_time(struct fw3_ipt_rule *r, struct fw3_time *time)
if (time->weekdays & 0xFE)
{
if (time->weekdays & 0xFE)
{
- for (i = 1, p = buf; i < 8; i++)
+ for (i = 1, p = buf
, rem = sizeof(buf)
; i < 8; i++)
{
if (fw3_hasbit(time->weekdays, i))
{
{
if (fw3_hasbit(time->weekdays, i))
{
- if (p > buf)
+ if (p > buf) {
+ if (rem <= 1)
+ break;
+
*p++ = ',';
*p++ = ',';
+ *p = 0;
+ rem--;
+ }
- p += sprintf(p, "%u", i);
+ len = snprintf(p, rem, "%u", i);
+
+ if (len < 0 || len >= rem)
+ break;
+
+ rem -= len;
+ p += len;
}
}
}
}
@@
-1192,15
+1231,15
@@
fw3_ipt_rule_time(struct fw3_ipt_rule *r, struct fw3_time *time)
void
fw3_ipt_rule_mark(struct fw3_ipt_rule *r, struct fw3_mark *mark)
{
void
fw3_ipt_rule_mark(struct fw3_ipt_rule *r, struct fw3_mark *mark)
{
- char buf[sizeof("0xFFFFFFFF/0xFFFFFFFF
\0
")];
+ char buf[sizeof("0xFFFFFFFF/0xFFFFFFFF")];
if (!mark || !mark->set)
return;
if (mark->mask < 0xFFFFFFFF)
if (!mark || !mark->set)
return;
if (mark->mask < 0xFFFFFFFF)
- s
printf(buf
, "0x%x/0x%x", mark->mark, mark->mask);
+ s
nprintf(buf, sizeof(buf)
, "0x%x/0x%x", mark->mark, mark->mask);
else
else
- s
printf(buf
, "0x%x", mark->mark);
+ s
nprintf(buf, sizeof(buf)
, "0x%x", mark->mark);
fw3_ipt_rule_addarg(r, false, "-m", "mark");
fw3_ipt_rule_addarg(r, mark->invert, "--mark", buf);
fw3_ipt_rule_addarg(r, false, "-m", "mark");
fw3_ipt_rule_addarg(r, mark->invert, "--mark", buf);
@@
-1209,12
+1248,12
@@
fw3_ipt_rule_mark(struct fw3_ipt_rule *r, struct fw3_mark *mark)
void
fw3_ipt_rule_dscp(struct fw3_ipt_rule *r, struct fw3_dscp *dscp)
{
void
fw3_ipt_rule_dscp(struct fw3_ipt_rule *r, struct fw3_dscp *dscp)
{
- char buf[sizeof("0xFF
\0
")];
+ char buf[sizeof("0xFF")];
if (!dscp || !dscp->set)
return;
if (!dscp || !dscp->set)
return;
- s
printf(buf
, "0x%x", dscp->dscp);
+ s
nprintf(buf, sizeof(buf)
, "0x%x", dscp->dscp);
fw3_ipt_rule_addarg(r, false, "-m", "dscp");
fw3_ipt_rule_addarg(r, dscp->invert, "--dscp", buf);
fw3_ipt_rule_addarg(r, false, "-m", "dscp");
fw3_ipt_rule_addarg(r, dscp->invert, "--dscp", buf);
@@
-1230,7
+1269,7
@@
fw3_ipt_rule_comment(struct fw3_ipt_rule *r, const char *fmt, ...)
return;
va_start(ap, fmt);
return;
va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf)
- 1
, fmt, ap);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fw3_ipt_rule_addarg(r, false, "-m", "comment");
va_end(ap);
fw3_ipt_rule_addarg(r, false, "-m", "comment");
@@
-1323,7
+1362,7
@@
static void
rule_print4(struct ipt_entry *e)
{
struct in_addr in_zero = { 0 };
rule_print4(struct ipt_entry *e)
{
struct in_addr in_zero = { 0 };
- char buf1[sizeof("255.255.255.255
\0")], buf2[sizeof("255.255.255.255\0
")];
+ char buf1[sizeof("255.255.255.255
")], buf2[sizeof("255.255.255.255
")];
char *pname;
if (e->ip.proto)
char *pname;
if (e->ip.proto)