40 lines
1.4 KiB
Diff
40 lines
1.4 KiB
Diff
# UNDF: UNDF-2026-000000823
|
|
# UNDF: (leave blank)
|
|
# CWE-407: Handler.is_host_notified() uses `host in self.notified_hosts` linear scan
|
|
# on list — O(H) per notification, O(H^2) total across all hosts
|
|
# Fix: maintain _notified_hosts_set: set alongside self.notified_hosts for O(1)
|
|
# Severity: MEDIUM — playbooks with 100+ hosts triggering same handler
|
|
# Measured: 250x op-count overhead at H=500
|
|
--- a/lib/ansible/playbook/handler.py
|
|
+++ b/lib/ansible/playbook/handler.py
|
|
@@ -29,6 +29,7 @@
|
|
def __init__(self, block=None, role=None, task_include=None):
|
|
self.notified_hosts = []
|
|
+ self._notified_hosts_set = set()
|
|
|
|
self.cached_name = False
|
|
|
|
@@ -55,6 +56,7 @@
|
|
def notify_host(self, host):
|
|
if not self.is_host_notified(host):
|
|
self.notified_hosts.append(host)
|
|
+ self._notified_hosts_set.add(host)
|
|
return True
|
|
return False
|
|
|
|
@@ -61,6 +63,7 @@
|
|
def remove_host(self, host):
|
|
try:
|
|
self.notified_hosts.remove(host)
|
|
+ self._notified_hosts_set.discard(host)
|
|
except ValueError:
|
|
raise AnsibleAssertionError(
|
|
|
|
@@ -69,5 +72,6 @@
|
|
def clear_hosts(self):
|
|
self.notified_hosts = []
|
|
+ self._notified_hosts_set = set()
|
|
|
|
def is_host_notified(self, host):
|
|
- return host in self.notified_hosts
|
|
+ return host in self._notified_hosts_set
|