Skip to content

Validate ACL, firewall and routing rule protocols against the list, not as a substring - #14359

Open
bhouse-nexthop wants to merge 3 commits into
apache:4.22from
bhouse-nexthop:fix-acl-protocol-validation
Open

bhouse-nexthop wants to merge 3 commits into
apache:4.22from
bhouse-nexthop:fix-acl-protocol-validation

Conversation

@bhouse-nexthop

@bhouse-nexthop bhouse-nexthop commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Description

createNetworkACL and updateNetworkACLItem accept protocol names that are not valid, such as cp, dp,ic or tcp,udp. The rule is stored and listed but never applied.

Fixes #14358

Why it breaks

NetworkACLServiceImpl.validateProtocol() checked a non-numeric protocol with supportedProtocolsForAclRules.contains(protocol.toLowerCase()). supportedProtocolsForAclRules is the string "tcp,udp,icmp,all", so this is a substring test: anything that appears inside it passes.

On the VR side, SetNetworkAclConfigItem doesn't recognise such a protocol, tries Integer.parseInt on it, and drops the rule with only a warning in the agent log. An allow or deny that the API accepted, and that the UI shows, silently does nothing.

How it is fixed

A new NetUtils.isProtocolInList(list, protocol) checks that the protocol is a whole entry of the comma-separated list, in any case.

  • Network ACLs: validateProtocol() now uses it. The field, the error message and the valid names are unchanged.
  • Other rule types: the same substring test was used for firewall rules, port forwarding and static NAT (FirewallManagerImpl), IPv6 firewall rules (Ipv6ServiceImpl) and routing firewall rules (RoutedIpv4ManagerImpl), so cp passed those too. They now use the helper as well.
  • Spaces in provider lists: the helper trims each list entry, because some providers advertise their protocols with a space after the comma (e.g. the VR's "tcp,udp,icmp, all"). The protocol being checked is not trimmed.

How to reproduce the old behaviour

  1. createNetworkACL aclid=<id> protocol=cp startport=22 endport=22 cidrlist=0.0.0.0/0 action=deny traffictype=ingress
    • Before: succeeds, and listNetworkACLs shows the rule with protocol cp. No rule for it appears on the VR, and the agent logs "Problem occurred when reading the entries in the ruleParts array".
    • After: Invalid protocol [cp]. Expected one of: [tcp,udp,icmp,all].

The old and new checks, side by side (jshell):

cp      -> old check passes: true, new: false
t       -> old check passes: true, new: false
dp,ic   -> old check passes: true, new: false
,       -> old check passes: true, new: false
tcp,udp -> old check passes: true, new: false

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

How Has This Been Tested?

  • New NetworkACLServiceImplTest.validateProtocolTestProtocolIsPartOfTheSupportedList checks that cp, t, dp,ic, , and tcp,udp are each rejected.
  • New NetUtilsTest.testIsProtocolInList:
    • whole entries match in any case, including entries listed with a leading space (all in "tcp,udp,icmp, all");
    • parts of an entry or of the list do not match (cp, dp,ic, tcp,udp, proxy against tcp-proxy, an empty string, all).
  • NetUtilsTest, Ipv6ServiceImplTest, RoutedIpv4ManagerImplTest and FirewallManagerTest still pass (utils and server build with checkstyle).
  • New validateProtocolTestProtocolNameInAnyCase checks that valid names are still accepted in any case (TCP, Udp, ICMP, All). The existing tests for valid names and protocol numbers still pass: NetworkACLServiceImplTest, 106 tests.
  • server builds with checkstyle.

How did you try to break this feature and the system with this change?

  • Valid input: every protocol name accepted today that is actually valid is still accepted, in any case. Numeric protocols take the other branch and are unaffected.
  • Locale: the comparison now lowercases with Locale.ROOT. Under a Turkish default locale the old check rejected ICMP, because it lowercased to a dotless ıcmp; it is now accepted.
  • Existing rules: a rule already stored with an invalid name would now fail validation on its next update. Such a rule has never been applied, so the error simply surfaces what was already broken.
  • Other open PRs: this is independent of VPC ACL: keep the ports and ICMP type of rules given by protocol number or as upper-case ICMP #14357, which also touches NetworkACLServiceImpl, in a different method.

validateProtocol() checked a protocol name with
"tcp,udp,icmp,all".contains(protocol), a substring test, so "cp", "t",
"dp,ic", "," or "tcp,udp" were accepted. Such a rule is stored and listed
but never applied: the VR side can't parse it and drops it with only a
warning. Compare against the entries of the list instead.

Fixes: apache#14358

Signed-off-by: Brad House <bhouse@nexthop.ai>
@bhouse-nexthop

Copy link
Copy Markdown
Collaborator Author

@vladimirpetrov @sureshanaparti could you take a look at this one? We'd like this fix to make it into the upcoming 4.22.2 release.

@codecov

codecov Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.92308% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 18.02%. Comparing base (2974af8) to head (fa1632d).
⚠️ Report is 1 commits behind head on 4.22.

Files with missing lines Patch % Lines
...c/main/java/com/cloud/network/Ipv6ServiceImpl.java 0.00% 1 Missing ⚠️
...om/cloud/network/firewall/FirewallManagerImpl.java 0.00% 1 Missing ⚠️
...ache/cloudstack/network/RoutedIpv4ManagerImpl.java 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               4.22   #14359      +/-   ##
============================================
- Coverage     18.02%   18.02%   -0.01%     
- Complexity    16250    16251       +1     
============================================
  Files          5936     5936              
  Lines        535823   535832       +9     
  Branches      65612    65614       +2     
============================================
- Hits          96582    96562      -20     
- Misses       428242   428271      +29     
  Partials      10999    10999              
Flag Coverage Δ
uitests 4.04% <ø> (ø)
unittests 19.09% <76.92%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Signed-off-by: Brad House <bhouse@nexthop.ai>
Comment thread server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java Outdated
The firewall (port forwarding, static NAT, firewall), IPv6 firewall and
routing firewall rule checks test the protocol against the provider's
supported protocols with the same substring test, so "cp" or "dp,ic"
passed them as well. Add NetUtils.isProtocolInList(), which matches a
whole entry of the comma-separated list in any case, trimming the entries
since some providers list them with a space after the comma ("tcp,udp,
icmp, all"), and use it for these checks and the network ACL one.

Signed-off-by: Brad House <bhouse@nexthop.ai>
@bhouse-nexthop bhouse-nexthop changed the title Network ACL: validate the protocol name against the list, not as a substring Validate ACL, firewall and routing rule protocols against the list, not as a substring Oct 8, 2026

@Damans227 Damans227 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @bhouse-nexthop, fix looks right. LGTM

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants