Skip to content

Commit f36e8ed

Browse files
committed
pcn-firewall: fix rules bad index access
add a couple of test as well Signed-off-by: Matteo Bertrone <m.bertrone@gmail.com>
1 parent ddec7b1 commit f36e8ed

5 files changed

Lines changed: 181 additions & 67 deletions

File tree

src/services/pcn-firewall/src/Chain.cpp

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,17 @@ ChainAppendOutputJsonObject Chain::append(ChainAppendInputJsonObject input) {
137137

138138
uint32_t id = rules_.size();
139139
conf.setId(id);
140-
ChainAppendOutputJsonObject result;
141140
addRule(id, conf);
141+
142+
ChainAppendOutputJsonObject result;
142143
result.setId(id);
144+
145+
// TODO improve
146+
// if (parent_.interactive_) {
147+
// ChainRule::applyAcceptEstablishedOptimization(*this);
148+
// parent_.attachInterfaces();
149+
// }
150+
143151
return result;
144152
}
145153

@@ -197,29 +205,9 @@ std::shared_ptr<spdlog::logger> Chain::logger() {
197205
}
198206

199207
uint32_t Chain::getNrRules() {
200-
/*
201-
* ChainRule::get returns only the valid rules to avoid segmentation faults
202-
* all around the code.
203-
* This methods returns the true number of rules, that can't be get from
204-
* ChainRule::get without
205-
* looking for the max id.
206-
*/
207208
return rules_.size();
208209
}
209210

210-
/*
211-
* returns only valid elements in the rules_ vector
212-
*/
213-
std::vector<std::shared_ptr<ChainRule>> Chain::getRealRuleList() {
214-
std::vector<std::shared_ptr<ChainRule>> rules;
215-
for (auto &rule : rules_) {
216-
if (rule) {
217-
rules.push_back(rule);
218-
}
219-
}
220-
return rules;
221-
}
222-
223211
void Chain::updateChain() {
224212
std::vector<Firewall::Program *> *programs;
225213
if (name == ChainNameEnum::INGRESS) {
@@ -247,10 +235,8 @@ void Chain::updateChain() {
247235
std::map<int, std::vector<uint64_t>> protocols;
248236
std::vector<std::vector<uint64_t>> flags;
249237

250-
auto rules = getRealRuleList();
251-
252238
// Looping through conntrack
253-
conntrack_from_rules_to_map(states, rules);
239+
conntrack_from_rules_to_map(states, rules_);
254240
if (!states.empty()) {
255241
// At least one rule requires a matching on conntrack, so it can be
256242
// injected.
@@ -276,7 +262,7 @@ void Chain::updateChain() {
276262
// Done looping through conntrack
277263

278264
// Looping through IP source
279-
ip_from_rules_to_map(SOURCE_TYPE, ips, rules);
265+
ip_from_rules_to_map(SOURCE_TYPE, ips, rules_);
280266
if (!ips.empty()) {
281267
// At least one rule requires a matching on ipsource, so inject
282268
// the module on the first available position
@@ -296,7 +282,7 @@ void Chain::updateChain() {
296282
// Done looping through IP source
297283

298284
// Looping through IP destination
299-
ip_from_rules_to_map(DESTINATION_TYPE, ips, rules);
285+
ip_from_rules_to_map(DESTINATION_TYPE, ips, rules_);
300286

301287
if (!ips.empty()) {
302288
// At least one rule requires a matching on ipdestination, so inject
@@ -317,7 +303,7 @@ void Chain::updateChain() {
317303
// Done looping through IP destination
318304

319305
// Looping through l4 protocol
320-
transportproto_from_rules_to_map(protocols, rules);
306+
transportproto_from_rules_to_map(protocols, rules_);
321307

322308
if (!protocols.empty()) {
323309
// At least one rule requires a matching on
@@ -339,7 +325,7 @@ void Chain::updateChain() {
339325
// Done looping through l4 protocol
340326

341327
// Looping through source port
342-
port_from_rules_to_map(SOURCE_TYPE, ports, rules);
328+
port_from_rules_to_map(SOURCE_TYPE, ports, rules_);
343329

344330
if (!ports.empty()) {
345331
// At least one rule requires a matching on source ports,
@@ -360,7 +346,7 @@ void Chain::updateChain() {
360346
// Done looping through source port
361347

362348
// Looping through destination port
363-
port_from_rules_to_map(DESTINATION_TYPE, ports, rules);
349+
port_from_rules_to_map(DESTINATION_TYPE, ports, rules_);
364350

365351
if (!ports.empty()) {
366352
// At least one rule requires a matching on source ports,
@@ -381,7 +367,7 @@ void Chain::updateChain() {
381367
// Done looping through destination port
382368

383369
// Looping through tcp flags
384-
flags_from_rules_to_map(flags, rules);
370+
flags_from_rules_to_map(flags, rules_);
385371

386372
if (!flags.empty()) {
387373
// At least one rule requires a matching on flags,
@@ -422,7 +408,7 @@ void Chain::updateChain() {
422408
}
423409
++index;
424410

425-
for (auto &rule : rules) {
411+
for (auto &rule : rules_) {
426412
actionlookup->updateTableValue(rule->getId(),
427413
ChainRule::ActionEnum_to_int(rule->getAction()));
428414
}
@@ -532,7 +518,7 @@ std::shared_ptr<ChainRule> Chain::getRule(const uint32_t &id) {
532518
}
533519

534520
std::vector<std::shared_ptr<ChainRule>> Chain::getRuleList() {
535-
auto rules(getRealRuleList());
521+
auto rules(rules_);
536522

537523
// Adding a "stub" default rule
538524
ChainRuleJsonObject defaultRule;
@@ -547,6 +533,11 @@ std::vector<std::shared_ptr<ChainRule>> Chain::getRuleList() {
547533
}
548534

549535
void Chain::addRule(const uint32_t &id, const ChainRuleJsonObject &conf) {
536+
537+
if (id > rules_.size()) {
538+
throw std::runtime_error("rule id not allowed");
539+
}
540+
550541
auto newRule = std::make_shared<ChainRule>(*this, conf);
551542

552543
// Forcing counters update
@@ -558,7 +549,7 @@ void Chain::addRule(const uint32_t &id, const ChainRuleJsonObject &conf) {
558549
throw new std::runtime_error("I won't be thrown");
559550

560551
} else if (rules_.size() <= id && newRule != nullptr) {
561-
rules_.resize(id + 1);
552+
rules_.resize(rules_.size() + 1);
562553
}
563554
if (rules_[id]) {
564555
logger()->info("Rule {0} overwritten!", id);
@@ -578,14 +569,14 @@ void Chain::addRuleList(const std::vector<ChainRuleJsonObject> &conf) {
578569
}
579570
}
580571

572+
// TODO check
581573
void Chain::replaceRule(const uint32_t &id, const ChainRuleJsonObject &conf) {
582-
delRule(id);
583574
uint32_t id_ = conf.getId();
584575
addRule(id_, conf);
585576
}
586577

587578
void Chain::delRule(const uint32_t &id) {
588-
if (rules_.size() < id || !rules_[id]) {
579+
if ((id >= rules_.size()) || (!rules_[id])) {
589580
throw std::runtime_error("There is no rule " + id);
590581
}
591582

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# PING testing rule appending
2+
3+
source "${BASH_SOURCE%/*}/../helpers.bash"
4+
5+
function fwcleanup {
6+
set +e
7+
polycubectl firewall del fw
8+
delete_veth 2
9+
}
10+
trap fwcleanup EXIT
11+
12+
echo -e '\nTest 1 \n'
13+
set -e
14+
set -x
15+
16+
create_veth 2
17+
18+
polycubectl firewall add fw loglevel=DEBUG
19+
polycubectl attach fw veth1
20+
21+
#matched rules
22+
polycubectl firewall fw chain INGRESS append src=10.0.0.1 dst=10.0.0.2 l4proto=ICMP action=FORWARD
23+
24+
#EGRESS CHAIN
25+
polycubectl firewall fw chain EGRESS append src=10.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
26+
27+
#ping
28+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
29+
30+
polycubectl firewall fw chain EGRESS del rule 0
31+
32+
test_fail sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
33+
34+
35+
polycubectl firewall fw chain EGRESS append src=10.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
36+
37+
polycubectl fw chain EGRESS show
38+
39+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
40+
41+
42+
polycubectl firewall fw chain EGRESS append src=10.0.0.0/24 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
43+
44+
polycubectl fw chain EGRESS show
45+
46+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
47+
48+
49+
50+
polycubectl firewall fw chain EGRESS del rule 1
51+
52+
polycubectl fw chain EGRESS show
53+
54+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
55+
56+
57+
polycubectl firewall fw chain EGRESS del rule 0
58+
59+
polycubectl fw chain EGRESS show
60+
61+
test_fail sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
62+
63+
64+
65+
polycubectl firewall fw chain EGRESS append src=10.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
66+
67+
polycubectl fw chain EGRESS show
68+
69+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
70+
71+
72+
polycubectl firewall fw chain EGRESS append src=10.0.0.0/24 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
73+
74+
polycubectl fw chain EGRESS show
75+
76+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
77+
78+
79+
80+
polycubectl firewall fw chain EGRESS del rule 0
81+
82+
polycubectl fw chain EGRESS show
83+
84+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
85+
86+
87+
polycubectl firewall fw chain EGRESS del rule 0
88+
89+
polycubectl fw chain EGRESS show
90+
91+
test_fail sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
92+
93+
94+
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# PING testing rule appending
2+
3+
source "${BASH_SOURCE%/*}/../helpers.bash"
4+
5+
function fwcleanup {
6+
set +e
7+
polycubectl firewall del fw
8+
delete_veth 2
9+
}
10+
trap fwcleanup EXIT
11+
12+
echo -e '\nTest 1 \n'
13+
set -e
14+
set -x
15+
16+
create_veth 2
17+
18+
polycubectl firewall add fw loglevel=DEBUG
19+
polycubectl attach fw veth1
20+
21+
#matched rules
22+
polycubectl firewall fw chain INGRESS append src=10.0.0.1 dst=10.0.0.2 l4proto=ICMP action=FORWARD
23+
24+
#EGRESS CHAIN
25+
polycubectl firewall fw chain EGRESS append src=10.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
26+
27+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
28+
29+
30+
polycubectl firewall fw chain EGRESS del rule 0
31+
32+
test_fail sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
33+
34+
35+
polycubectl firewall fw chain EGRESS append src=10.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
36+
37+
polycubectl fw chain EGRESS show
38+
39+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
40+
41+
42+
polycubectl firewall fw chain EGRESS rule 0 add src=20.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
43+
44+
polycubectl fw chain EGRESS show
45+
46+
test_fail sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
47+
48+
49+
50+
polycubectl firewall fw chain EGRESS del rule 0
51+
52+
polycubectl fw chain EGRESS show
53+
54+
test_fail sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1
55+
56+
57+
polycubectl firewall fw chain EGRESS append src=10.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
58+
59+
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5 -w 1

src/services/pcn-firewall/test/ping/test_ping_7.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ polycubectl attach fw veth1
2020

2121
#INGRESS CHAIN
2222
#matched rules
23-
polycubectl firewall fw chain INGRESS rule add 62 src=10.0.0.1 dst=10.0.0.2 l4proto=ICMP action=FORWARD
23+
polycubectl firewall fw chain INGRESS rule add 0 src=10.0.0.1 dst=10.0.0.2 l4proto=ICMP action=FORWARD
2424

2525
#EGRESS CHAIN
2626
#matched rules
27-
polycubectl firewall fw chain EGRESS rule add 62 src=10.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
27+
polycubectl firewall fw chain EGRESS rule add 0 src=10.0.0.2/32 dst=10.0.0.1/32 l4proto=ICMP action=FORWARD
2828

2929
#ping
3030
sudo ip netns exec ns1 ping 10.0.0.2 -c 2 -i 0.5

src/services/pcn-firewall/test/ping/test_ping_8.sh

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)