Class: FiberAudit::Static::Rules::BlockingSubprocess
- Defined in:
- lib/fiber_audit/static/rules/blocking_subprocess.rb
Overview
FA1001: Subprocess lifecycle operations that may interfere with the fiber scheduler. Detects subprocess creation, replacement, waiting, detachment, and stream lifecycle operations.
Operations are classified into semantic categories:
- creation: spawning a new process (info)
- replacement: replacing the current process via exec (info)
- waiting: blocking waits for subprocess completion (medium)
- detach: detaching a subprocess without waiting (info)
- stream: subprocess pipe/stream lifecycle via IO.popen (medium)
Severity: info for creation/replacement/detach, medium for waits/stream. These are scheduler-cooperation requirements, so execution context does not by itself escalate them to critical.
Constant Summary collapse
- TARGETS =
OperationVocabulary::FA1001_TARGETS
- BARE_KERNEL_METHODS =
OperationVocabulary::FA1001_KERNEL_METHODS
- OPERATION_CATEGORY =
Per-operation semantic category
{ # Creation (info) - spawning a new process 'Kernel.spawn' => :creation, 'Process.spawn' => :creation, # Replacement (info) - replacing current process via exec 'Kernel.exec' => :replacement, 'Process.exec' => :replacement, # Waiting (medium) - blocking waits for subprocess completion 'Kernel.system' => :waiting, 'Process.wait' => :waiting, 'Process.wait2' => :waiting, 'Process.waitpid' => :waiting, 'Process.waitpid2' => :waiting, 'Process.waitall' => :waiting, 'Process::Status.wait' => :waiting, 'Open3.capture2' => :waiting, 'Open3.capture2e' => :waiting, 'Open3.capture3' => :waiting, 'Open3.pipeline' => :waiting, # Detach (info) - detaching subprocess without waiting 'Process.detach' => :detach, # Stream (medium) - subprocess pipe/stream lifecycle 'IO.popen' => :stream }.freeze
- CATEGORY_METADATA =
Per-category metadata
{ creation: { severity: :info, title: 'Subprocess creation', message: 'Spawning a subprocess may leave background processes that outlive the fiber scheduler session.', remediation: 'Track spawned processes or move subprocess creation outside the fiber-scheduled path.' }, replacement: { severity: :info, title: 'Process replacement', message: 'Process replacement via exec replaces the current process image, terminating the fiber scheduler.', remediation: 'Avoid exec in fiber-scheduled code; prefer subprocess creation with explicit lifecycle management.' }, waiting: { severity: :medium, title: 'Subprocess wait', message: 'Subprocess waiting requires scheduler process-wait cooperation in a non-blocking Fiber.', remediation: 'Verify scheduler process_wait support and runtime progress, ' \ 'or move waits outside the fiber-scheduled path.' }, detach: { severity: :info, title: 'Subprocess detach', message: 'Detaching a subprocess may leave it unmanaged by the fiber scheduler.', remediation: 'Avoid detaching subprocesses in fiber-scheduled code; use explicit lifecycle management.' }, stream: { severity: :medium, title: 'Subprocess pipe stream', message: 'Subprocess pipe I/O requires scheduler cooperation while the stream is open.', remediation: 'Verify scheduler-aware I/O and runtime progress on the pipe, ' \ 'or move pipe operations outside the fiber-scheduled path.' } }.freeze
Constants inherited from Base
FiberAudit::Static::Rules::Base::CONTEXT_CEILING
Instance Method Summary collapse
Methods inherited from Base
confidence, default_confidence, default_severity, description, id, #initialize, severity
Constructor Details
This class inherits a constructor from FiberAudit::Static::Rules::Base
Instance Method Details
#analyze(call_sites:) ⇒ Object
97 98 99 100 101 102 103 |
# File 'lib/fiber_audit/static/rules/blocking_subprocess.rb', line 97 def analyze(call_sites:) call_sites.filter_map do |site| next unless (match = match_call_site(site)) build_finding(site, match) end end |