From a457fc65507087eedd9bd4a160220b9bc76427f7 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Wed, 30 Apr 2014 11:41:18 -0400 Subject: [PATCH] nwfilter: Validate rule after parsing An IP or IPv6 rule with port specification but without protocol specification cannot be instantiated by ebtables. The documentation points to 'protocol' being required but implementation does not enforce it to be given. Implement a rule validation function that checks whether the rule is valid when it is defined. This for example prevents the definition of rules like: where a protocol attribute would be required for it to be valid and for ebtables to be able to instantiate it. A valid rule then is: Signed-off-by: Stefan Berger --- src/conf/nwfilter_conf.c | 62 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 90da0b5837..67b5482a1d 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -2095,6 +2095,66 @@ virNWFilterRuleDefFixupIPSet(ipHdrDataDefPtr ipHdr) } } + +/* + * virNWFilterRuleValidate + * + * Perform some basic rule validation to prevent rules from being + * defined that cannot be instantiated. + */ +static int +virNWFilterRuleValidate(virNWFilterRuleDefPtr rule) +{ + int ret = 0; + portDataDefPtr portData = NULL; + nwItemDescPtr dataProtocolID; + const char *protocol; + + switch (rule->prtclType) { + case VIR_NWFILTER_RULE_PROTOCOL_IP: + portData = &rule->p.ipHdrFilter.portData; + protocol = "IP"; + dataProtocolID = &rule->p.ipHdrFilter.ipHdr.dataProtocolID; + /* fall through */ + case VIR_NWFILTER_RULE_PROTOCOL_IPV6: + if (portData == NULL) { + portData = &rule->p.ipv6HdrFilter.portData; + protocol = "IPv6"; + dataProtocolID = &rule->p.ipv6HdrFilter.ipHdr.dataProtocolID; + } + if (HAS_ENTRY_ITEM(&portData->dataSrcPortStart) || + HAS_ENTRY_ITEM(&portData->dataDstPortStart) || + HAS_ENTRY_ITEM(&portData->dataSrcPortEnd) || + HAS_ENTRY_ITEM(&portData->dataDstPortEnd)) { + if (HAS_ENTRY_ITEM(dataProtocolID)) { + switch (dataProtocolID->u.u8) { + case 6: /* tcp */ + case 17: /* udp */ + case 33: /* dccp */ + case 132: /* sctp */ + break; + default: + ret = -1; + } + } else { + ret = -1; + } + if (ret < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s rule with port specification requires " + "protocol specification with protocol to be " + "either one of tcp(6), udp(17), dccp(33), or " + "sctp(132)"), protocol); + } + } + break; + default: + break; + } + + return ret; +} + static void virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule) { @@ -2391,6 +2451,8 @@ virNWFilterRuleParse(xmlNodePtr node) virAttr[i].att) < 0) { goto err_exit; } + if (virNWFilterRuleValidate(ret) < 0) + goto err_exit; break; } if (!found) { -- GitLab