summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-05-08 12:45:25 +0200
committerFlorian Westphal <fw@strlen.de>2018-05-10 02:31:05 +0200
commit652b98e79371102f8e5edf572a7a5c2aa282c51a (patch)
tree365f9bc3f4a3e0e1a691fe99d7977fb4bf8f4489
parent49f4993313b7a775588ee3dce448c8dbc2624f95 (diff)
xtables-compat: fix wildcard detection
if (outiface[len] == '\0') is always true. 'eth+' is stored as 'eth' with length 3, so "eth"[3] == 0. 'eth' is stored as 'eth\0' with length 4, so "eth\0"[4] is also true. Add a helper for this, then use it. Signed-off-by: Florian Westphal <fw@strlen.de>
-rw-r--r--iptables/nft-shared.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index fcc33d28..ecc54024 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -217,6 +217,30 @@ bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
return true;
}
+static void parse_ifname(const char *name, unsigned int len, char *dst, unsigned char *mask)
+{
+ if (len == 0)
+ return;
+
+ memcpy(dst, name, len);
+ if (name[len - 1] == '\0') {
+ if (mask)
+ memset(mask, 0xff, len);
+ return;
+ }
+
+ if (len >= IFNAMSIZ)
+ return;
+
+ /* wildcard */
+ dst[len++] = '+';
+ if (len >= IFNAMSIZ)
+ return;
+ dst[len++] = 0;
+ if (mask)
+ memset(mask, 0xff, len + 1);
+}
+
int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
unsigned char *iniface_mask, char *outiface,
unsigned char *outiface_mask, uint8_t *invflags)
@@ -249,30 +273,14 @@ int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
*invflags |= IPT_INV_VIA_IN;
- memcpy(iniface, ifname, len);
-
- if (iniface[len] == '\0')
- memset(iniface_mask, 0xff, len);
- else {
- iniface[len] = '+';
- iniface[len+1] = '\0';
- memset(iniface_mask, 0xff, len + 1);
- }
+ parse_ifname(ifname, len, iniface, iniface_mask);
break;
case NFT_META_OIFNAME:
ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
*invflags |= IPT_INV_VIA_OUT;
- memcpy(outiface, ifname, len);
-
- if (outiface[len] == '\0')
- memset(outiface_mask, 0xff, len);
- else {
- outiface[len] = '+';
- outiface[len+1] = '\0';
- memset(outiface_mask, 0xff, len + 1);
- }
+ parse_ifname(ifname, len, outiface, outiface_mask);
break;
default:
return -1;