fiber_audit 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ARCHITECTURE.md +26 -24
- data/CHANGELOG.md +34 -0
- data/README.md +42 -18
- data/lib/fiber_audit/cli.rb +16 -4
- data/lib/fiber_audit/operation_vocabulary.rb +2 -1
- data/lib/fiber_audit/runtime/active_operations.rb +19 -5
- data/lib/fiber_audit/runtime/execution_context.rb +55 -43
- data/lib/fiber_audit/runtime/probes/base.rb +24 -3
- data/lib/fiber_audit/runtime/probes/subprocess.rb +89 -8
- data/lib/fiber_audit/runtime/probes/thread_state.rb +0 -14
- data/lib/fiber_audit/runtime/rails_integration.rb +51 -10
- data/lib/fiber_audit/runtime/scheduler_observer.rb +54 -18
- data/lib/fiber_audit/runtime/scheduler_snapshot.rb +113 -0
- data/lib/fiber_audit/runtime/watchdog.rb +44 -2
- data/lib/fiber_audit/runtime.rb +1 -0
- data/lib/fiber_audit/static/call_site_extractor.rb +1 -0
- data/lib/fiber_audit/static/rules/base.rb +19 -0
- data/lib/fiber_audit/static/rules/blocking_subprocess.rb +90 -10
- data/lib/fiber_audit/static/rules/direct_socket.rb +8 -9
- data/lib/fiber_audit/static/rules/io_select.rb +6 -6
- data/lib/fiber_audit/static/rules/net_http_in_request.rb +11 -8
- data/lib/fiber_audit/static/rules/synchronization.rb +13 -8
- data/lib/fiber_audit/static/rules/thread_current_state.rb +18 -20
- data/lib/fiber_audit/static/rules/thread_join.rb +9 -7
- data/lib/fiber_audit/version.rb +1 -1
- metadata +2 -1
|
@@ -9,17 +9,90 @@ require_relative '../../operation_vocabulary'
|
|
|
9
9
|
module FiberAudit
|
|
10
10
|
module Static
|
|
11
11
|
module Rules
|
|
12
|
+
# FA1001: Subprocess lifecycle operations that may interfere with
|
|
13
|
+
# the fiber scheduler. Detects subprocess creation, replacement,
|
|
14
|
+
# waiting, detachment, and stream lifecycle operations.
|
|
15
|
+
#
|
|
16
|
+
# Operations are classified into semantic categories:
|
|
17
|
+
# - creation: spawning a new process (info)
|
|
18
|
+
# - replacement: replacing the current process via exec (info)
|
|
19
|
+
# - waiting: blocking waits for subprocess completion (medium)
|
|
20
|
+
# - detach: detaching a subprocess without waiting (info)
|
|
21
|
+
# - stream: subprocess pipe/stream lifecycle via IO.popen (medium)
|
|
22
|
+
#
|
|
23
|
+
# Severity: info for creation/replacement/detach, medium for waits/stream.
|
|
24
|
+
# These are scheduler-cooperation requirements, so execution context does
|
|
25
|
+
# not by itself escalate them to critical.
|
|
12
26
|
class BlockingSubprocess < Base
|
|
13
27
|
id 'FA1001'
|
|
14
|
-
severity :
|
|
28
|
+
severity :medium
|
|
15
29
|
default_confidence :high
|
|
16
|
-
description '
|
|
30
|
+
description 'Subprocess lifecycle operations may interfere with the fiber scheduler'
|
|
17
31
|
|
|
18
32
|
TARGETS = OperationVocabulary::FA1001_TARGETS
|
|
19
33
|
BARE_KERNEL_METHODS = OperationVocabulary::FA1001_KERNEL_METHODS
|
|
20
34
|
|
|
21
|
-
|
|
22
|
-
|
|
35
|
+
# Per-operation semantic category
|
|
36
|
+
OPERATION_CATEGORY = {
|
|
37
|
+
# Creation (info) - spawning a new process
|
|
38
|
+
'Kernel.spawn' => :creation,
|
|
39
|
+
'Process.spawn' => :creation,
|
|
40
|
+
# Replacement (info) - replacing current process via exec
|
|
41
|
+
'Kernel.exec' => :replacement,
|
|
42
|
+
'Process.exec' => :replacement,
|
|
43
|
+
# Waiting (medium) - blocking waits for subprocess completion
|
|
44
|
+
'Kernel.system' => :waiting,
|
|
45
|
+
'Process.wait' => :waiting,
|
|
46
|
+
'Process.wait2' => :waiting,
|
|
47
|
+
'Process.waitpid' => :waiting,
|
|
48
|
+
'Process.waitpid2' => :waiting,
|
|
49
|
+
'Process.waitall' => :waiting,
|
|
50
|
+
'Process::Status.wait' => :waiting,
|
|
51
|
+
'Open3.capture2' => :waiting,
|
|
52
|
+
'Open3.capture2e' => :waiting,
|
|
53
|
+
'Open3.capture3' => :waiting,
|
|
54
|
+
'Open3.pipeline' => :waiting,
|
|
55
|
+
# Detach (info) - detaching subprocess without waiting
|
|
56
|
+
'Process.detach' => :detach,
|
|
57
|
+
# Stream (medium) - subprocess pipe/stream lifecycle
|
|
58
|
+
'IO.popen' => :stream
|
|
59
|
+
}.freeze
|
|
60
|
+
|
|
61
|
+
# Per-category metadata
|
|
62
|
+
CATEGORY_METADATA = {
|
|
63
|
+
creation: {
|
|
64
|
+
severity: :info,
|
|
65
|
+
title: 'Subprocess creation',
|
|
66
|
+
message: 'Spawning a subprocess may leave background processes that outlive the fiber scheduler session.',
|
|
67
|
+
remediation: 'Track spawned processes or move subprocess creation outside the fiber-scheduled path.'
|
|
68
|
+
},
|
|
69
|
+
replacement: {
|
|
70
|
+
severity: :info,
|
|
71
|
+
title: 'Process replacement',
|
|
72
|
+
message: 'Process replacement via exec replaces the current process image, terminating the fiber scheduler.',
|
|
73
|
+
remediation: 'Avoid exec in fiber-scheduled code; prefer subprocess creation with explicit lifecycle management.'
|
|
74
|
+
},
|
|
75
|
+
waiting: {
|
|
76
|
+
severity: :medium,
|
|
77
|
+
title: 'Subprocess wait',
|
|
78
|
+
message: 'Subprocess waiting requires scheduler process-wait cooperation in a non-blocking Fiber.',
|
|
79
|
+
remediation: 'Verify scheduler process_wait support and runtime progress, ' \
|
|
80
|
+
'or move waits outside the fiber-scheduled path.'
|
|
81
|
+
},
|
|
82
|
+
detach: {
|
|
83
|
+
severity: :info,
|
|
84
|
+
title: 'Subprocess detach',
|
|
85
|
+
message: 'Detaching a subprocess may leave it unmanaged by the fiber scheduler.',
|
|
86
|
+
remediation: 'Avoid detaching subprocesses in fiber-scheduled code; use explicit lifecycle management.'
|
|
87
|
+
},
|
|
88
|
+
stream: {
|
|
89
|
+
severity: :medium,
|
|
90
|
+
title: 'Subprocess pipe stream',
|
|
91
|
+
message: 'Subprocess pipe I/O requires scheduler cooperation while the stream is open.',
|
|
92
|
+
remediation: 'Verify scheduler-aware I/O and runtime progress on the pipe, ' \
|
|
93
|
+
'or move pipe operations outside the fiber-scheduled path.'
|
|
94
|
+
}
|
|
95
|
+
}.freeze
|
|
23
96
|
|
|
24
97
|
def analyze(call_sites:)
|
|
25
98
|
call_sites.filter_map do |site|
|
|
@@ -60,11 +133,14 @@ module FiberAudit
|
|
|
60
133
|
def build_finding(site, match)
|
|
61
134
|
operation = "#{match[:constant]}.#{match[:method]}"
|
|
62
135
|
context = site.execution_context || :unknown
|
|
63
|
-
|
|
136
|
+
category = OPERATION_CATEGORY.fetch(operation, :waiting)
|
|
137
|
+
metadata = CATEGORY_METADATA.fetch(category)
|
|
138
|
+
base_severity = metadata[:severity]
|
|
139
|
+
sev = advisory_severity(base_severity)
|
|
64
140
|
|
|
65
141
|
Finding.new(
|
|
66
142
|
rule_id: self.class.id,
|
|
67
|
-
title:
|
|
143
|
+
title: metadata[:title],
|
|
68
144
|
category: :subprocess,
|
|
69
145
|
severity: sev,
|
|
70
146
|
confidence: match[:confidence],
|
|
@@ -72,15 +148,19 @@ module FiberAudit
|
|
|
72
148
|
symbol: site.enclosing_symbol,
|
|
73
149
|
operation: operation,
|
|
74
150
|
execution_context: context,
|
|
75
|
-
message:
|
|
151
|
+
message: metadata[:message],
|
|
76
152
|
evidence: [
|
|
77
153
|
Evidence.new(
|
|
78
154
|
source: :static,
|
|
79
|
-
message: "Matched #{operation}",
|
|
80
|
-
details: {
|
|
155
|
+
message: "Matched #{operation} (#{category})",
|
|
156
|
+
details: {
|
|
157
|
+
receiver: match[:constant],
|
|
158
|
+
method: match[:method],
|
|
159
|
+
semantic: category
|
|
160
|
+
}
|
|
81
161
|
)
|
|
82
162
|
],
|
|
83
|
-
remediation:
|
|
163
|
+
remediation: metadata[:remediation]
|
|
84
164
|
)
|
|
85
165
|
end
|
|
86
166
|
end
|
|
@@ -9,23 +9,22 @@ require_relative '../../operation_vocabulary'
|
|
|
9
9
|
module FiberAudit
|
|
10
10
|
module Static
|
|
11
11
|
module Rules
|
|
12
|
-
# FA1006 – Detects direct socket
|
|
13
|
-
# scheduler
|
|
12
|
+
# FA1006 – Detects direct socket construction whose DNS, connection, and
|
|
13
|
+
# later I/O require scheduler cooperation. Advisory rule with :low default.
|
|
14
14
|
class DirectSocket < Base
|
|
15
15
|
id 'FA1006'
|
|
16
|
-
severity :
|
|
16
|
+
severity :low
|
|
17
17
|
default_confidence :high
|
|
18
|
-
description '
|
|
18
|
+
description 'Direct socket paths require scheduler-aware DNS and I/O cooperation.'
|
|
19
19
|
|
|
20
20
|
TITLE = 'Direct socket creation'
|
|
21
21
|
CATEGORY = :network
|
|
22
22
|
|
|
23
23
|
EXACT = OperationVocabulary::FA1006_EXACT
|
|
24
24
|
|
|
25
|
-
MESSAGE = '
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'socket operations cooperate with the active Fiber scheduler.'
|
|
25
|
+
MESSAGE = 'This socket path may require scheduler cooperation for DNS, connection, or subsequent I/O.'
|
|
26
|
+
REMEDIATION = 'Distinguish allocation from DNS/connect/I/O, then verify ' \
|
|
27
|
+
'the active scheduler hooks and runtime progress.'
|
|
29
28
|
|
|
30
29
|
class << self
|
|
31
30
|
def title = TITLE
|
|
@@ -88,7 +87,7 @@ module FiberAudit
|
|
|
88
87
|
rule_id: self.class.id,
|
|
89
88
|
title: self.class.title,
|
|
90
89
|
category: self.class.category,
|
|
91
|
-
severity:
|
|
90
|
+
severity: advisory_severity(:low),
|
|
92
91
|
confidence: site.confidence,
|
|
93
92
|
location: site.location,
|
|
94
93
|
symbol: site.enclosing_symbol,
|
|
@@ -9,19 +9,19 @@ require_relative '../../operation_vocabulary'
|
|
|
9
9
|
module FiberAudit
|
|
10
10
|
module Static
|
|
11
11
|
module Rules
|
|
12
|
-
# FA1005: Detects explicit IO.select
|
|
13
|
-
#
|
|
12
|
+
# FA1005: Detects explicit IO.select scheduler-capability requirements.
|
|
13
|
+
# Advisory rule with :medium default.
|
|
14
14
|
class IOSelect < Base
|
|
15
15
|
id 'FA1005'
|
|
16
16
|
severity :medium
|
|
17
17
|
default_confidence :high
|
|
18
|
-
description 'Explicit IO.select
|
|
18
|
+
description 'Explicit IO.select requires scheduler io_select cooperation'
|
|
19
19
|
|
|
20
20
|
TITLE = 'Explicit IO.select call'
|
|
21
21
|
CATEGORY = :blocking_io
|
|
22
22
|
|
|
23
|
-
MESSAGE = 'IO.select
|
|
24
|
-
REMEDIATION = '
|
|
23
|
+
MESSAGE = 'IO.select requires scheduler io_select support when used from a non-blocking Fiber.'
|
|
24
|
+
REMEDIATION = 'Verify the selected scheduler implements io_select and confirm runtime progress under load.'
|
|
25
25
|
|
|
26
26
|
TARGETS = OperationVocabulary::FA1005_TARGETS
|
|
27
27
|
|
|
@@ -79,7 +79,7 @@ module FiberAudit
|
|
|
79
79
|
rule_id: self.class.id,
|
|
80
80
|
title: TITLE,
|
|
81
81
|
category: CATEGORY,
|
|
82
|
-
severity:
|
|
82
|
+
severity: advisory_severity(:medium),
|
|
83
83
|
confidence: confidence,
|
|
84
84
|
location: site.location,
|
|
85
85
|
symbol: site.enclosing_symbol,
|
|
@@ -9,19 +9,22 @@ require_relative '../../operation_vocabulary'
|
|
|
9
9
|
module FiberAudit
|
|
10
10
|
module Static
|
|
11
11
|
module Rules
|
|
12
|
-
# FA1007: Detects
|
|
12
|
+
# FA1007: Detects HTTP scheduler-cooperation requirements in request-like contexts.
|
|
13
13
|
# Targets Net::HTTP.{get,get_response,start,request}, URI.open, OpenURI.open_uri.
|
|
14
14
|
# Excludes Net::HTTP.get_print. Emits only for request/middleware/websocket/callback.
|
|
15
|
+
#
|
|
16
|
+
# Advisory rule with :medium default, no context ceiling.
|
|
15
17
|
class NetHTTPInRequest < Base
|
|
16
18
|
id 'FA1007'
|
|
17
|
-
severity :
|
|
19
|
+
severity :medium
|
|
18
20
|
default_confidence :high
|
|
19
|
-
description '
|
|
21
|
+
description 'HTTP calls require scheduler-aware DNS, socket, and TLS cooperation in request contexts'
|
|
20
22
|
|
|
21
|
-
TITLE = '
|
|
23
|
+
TITLE = 'HTTP scheduler-cooperation requirement'
|
|
22
24
|
CATEGORY = :network
|
|
23
|
-
MESSAGE = '
|
|
24
|
-
REMEDIATION = '
|
|
25
|
+
MESSAGE = 'HTTP activity requires scheduler-aware DNS and I/O cooperation in a non-blocking Fiber.'
|
|
26
|
+
REMEDIATION = 'Verify the selected HTTP/TLS/DNS stack and active scheduler ' \
|
|
27
|
+
'under load; investigate correlated stalls.'
|
|
25
28
|
|
|
26
29
|
NET_HTTP_METHODS = OperationVocabulary::FA1007_NET_HTTP_METHODS
|
|
27
30
|
URI_METHODS = OperationVocabulary::FA1007_URI_METHODS
|
|
@@ -82,7 +85,7 @@ module FiberAudit
|
|
|
82
85
|
def build_finding(site, match)
|
|
83
86
|
context = site.execution_context
|
|
84
87
|
sev, conf = if match[:type] == :net_http
|
|
85
|
-
[
|
|
88
|
+
[advisory_severity(:medium), site.confidence]
|
|
86
89
|
else
|
|
87
90
|
%i[medium low]
|
|
88
91
|
end
|
|
@@ -101,7 +104,7 @@ module FiberAudit
|
|
|
101
104
|
evidence: [
|
|
102
105
|
FiberAudit::Evidence.new(
|
|
103
106
|
source: 'static_analysis',
|
|
104
|
-
message: "
|
|
107
|
+
message: "HTTP scheduler-cooperation point: #{match[:operation]}",
|
|
105
108
|
details: { receiver: site.receiver_constant, method: site.method_name, context: context }
|
|
106
109
|
)
|
|
107
110
|
],
|
|
@@ -9,20 +9,24 @@ require_relative '../../operation_vocabulary'
|
|
|
9
9
|
module FiberAudit
|
|
10
10
|
module Static
|
|
11
11
|
module Rules
|
|
12
|
+
# FA1003: Thread synchronization primitives that may interfere with
|
|
13
|
+
# fiber scheduler cooperation. Advisory rule with :low default.
|
|
14
|
+
#
|
|
15
|
+
# Detects Mutex, ConditionVariable, Monitor, and MonitorMixin
|
|
16
|
+
# synchronization operations. try_lock is treated as :info since
|
|
17
|
+
# it's non-blocking but indicates thread-oriented synchronization.
|
|
12
18
|
class Synchronization < Base
|
|
13
19
|
id 'FA1003'
|
|
14
|
-
severity :
|
|
20
|
+
severity :low
|
|
15
21
|
default_confidence :high
|
|
16
|
-
description 'Thread synchronization
|
|
22
|
+
description 'Thread synchronization may interfere with fiber scheduler cooperation'
|
|
17
23
|
|
|
18
24
|
RULE_TITLE = 'Thread synchronization'
|
|
19
25
|
RULE_CATEGORY = :synchronization
|
|
20
26
|
TARGETS = OperationVocabulary::FA1003_TARGETS
|
|
21
|
-
TRY_LOCK_MSG = 'Mutex
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
REMEDIATION = 'Use scheduler-aware synchronization primitives, or verify ' \
|
|
25
|
-
'contention and scheduler behaviour under load.'
|
|
27
|
+
TRY_LOCK_MSG = 'Mutex#try_lock is non-blocking and identifies a thread-oriented coordination point.'
|
|
28
|
+
NORMAL_MSG = 'Synchronization contention requires scheduler block/unblock cooperation in a non-blocking Fiber.'
|
|
29
|
+
REMEDIATION = 'Verify scheduler coordination and contention behavior under load; investigate correlated stalls.'
|
|
26
30
|
|
|
27
31
|
def analyze(call_sites:)
|
|
28
32
|
explicit_monitor_mixins = explicit_monitor_mixin_classes(call_sites)
|
|
@@ -98,7 +102,8 @@ module FiberAudit
|
|
|
98
102
|
def build_finding(site, target, method)
|
|
99
103
|
try_lock = target == 'Mutex' && method == :try_lock
|
|
100
104
|
operation = "#{target}##{method}"
|
|
101
|
-
|
|
105
|
+
# try_lock has fixed :info, no config override
|
|
106
|
+
severity = try_lock ? :info : advisory_severity(:low)
|
|
102
107
|
confidence = try_lock ? :high : site.confidence
|
|
103
108
|
message = try_lock ? TRY_LOCK_MSG : NORMAL_MSG
|
|
104
109
|
evidence = Evidence.new(source: operation, message: message,
|
|
@@ -9,27 +9,32 @@ require_relative '../../operation_vocabulary'
|
|
|
9
9
|
module FiberAudit
|
|
10
10
|
module Static
|
|
11
11
|
module Rules
|
|
12
|
-
# Detect thread-variable
|
|
12
|
+
# FA1004: Detect thread-variable state access.
|
|
13
|
+
#
|
|
14
|
+
# Detects only thread_variable_get/set operations, not Thread.current[]
|
|
15
|
+
# index operations. Thread variables are shared across all fibers on the
|
|
16
|
+
# same thread and may leak request-local data.
|
|
13
17
|
class ThreadCurrentState < Base
|
|
14
18
|
id 'FA1004'
|
|
15
19
|
severity :high
|
|
16
20
|
confidence :high
|
|
17
|
-
description 'Thread
|
|
21
|
+
description 'Thread thread variables in fiber code may be shared across fibers and leak request-local data'
|
|
18
22
|
|
|
19
|
-
TITLE = 'Thread
|
|
23
|
+
TITLE = 'Thread thread variables in fiber code'
|
|
20
24
|
CATEGORY = :thread_local
|
|
21
|
-
MESSAGE = 'Thread
|
|
22
|
-
|
|
25
|
+
MESSAGE = 'Thread thread variables are shared across all fibers on the same thread ' \
|
|
26
|
+
'and may leak request-local data between concurrent requests.'
|
|
27
|
+
REMEDIATION = 'Prefer fiber-local storage (Fiber[:key]) or framework-provided ' \
|
|
28
|
+
'request-local state over thread_variable_get/set.'
|
|
23
29
|
|
|
24
30
|
THREAD_VARIABLE_METHODS = OperationVocabulary::FA1004_THREAD_VARIABLE_METHODS
|
|
25
|
-
INDEX_METHODS = OperationVocabulary::FA1004_INDEX_METHODS
|
|
26
31
|
|
|
27
32
|
def analyze(call_sites:)
|
|
28
33
|
findings = []
|
|
29
34
|
call_sites.each do |site|
|
|
30
35
|
next if skip?(site)
|
|
31
36
|
|
|
32
|
-
finding = match_thread_variable(site)
|
|
37
|
+
finding = match_thread_variable(site)
|
|
33
38
|
findings << finding if finding
|
|
34
39
|
end
|
|
35
40
|
findings
|
|
@@ -74,19 +79,8 @@ module FiberAudit
|
|
|
74
79
|
build_finding(site, :high, :high, operation(site))
|
|
75
80
|
end
|
|
76
81
|
|
|
77
|
-
def match_index_op(site)
|
|
78
|
-
return unless INDEX_METHODS.include?(site.method_name)
|
|
79
|
-
return unless site.receiver_source == 'Thread.current'
|
|
80
|
-
|
|
81
|
-
build_finding(site, :medium, :high, operation(site))
|
|
82
|
-
end
|
|
83
|
-
|
|
84
82
|
def operation(site)
|
|
85
|
-
|
|
86
|
-
"Thread.current.#{site.method_name}"
|
|
87
|
-
else
|
|
88
|
-
"Thread.#{site.method_name}"
|
|
89
|
-
end
|
|
83
|
+
"Thread.#{site.method_name}"
|
|
90
84
|
end
|
|
91
85
|
|
|
92
86
|
def build_finding(site, default_sev, conf, operation)
|
|
@@ -104,7 +98,11 @@ module FiberAudit
|
|
|
104
98
|
operation: operation,
|
|
105
99
|
execution_context: context,
|
|
106
100
|
message: MESSAGE,
|
|
107
|
-
evidence: [Evidence.new(
|
|
101
|
+
evidence: [Evidence.new(
|
|
102
|
+
source: site.receiver_source,
|
|
103
|
+
message: "Thread thread variable access via #{site.method_name}",
|
|
104
|
+
details: { operation: operation, receiver: site.receiver_source }
|
|
105
|
+
)],
|
|
108
106
|
remediation: REMEDIATION
|
|
109
107
|
)
|
|
110
108
|
end
|
|
@@ -9,7 +9,7 @@ require_relative '../../operation_vocabulary'
|
|
|
9
9
|
module FiberAudit
|
|
10
10
|
module Static
|
|
11
11
|
module Rules
|
|
12
|
-
# FA1002: Thread#join / Thread#value
|
|
12
|
+
# FA1002: Thread#join / Thread#value are scheduler coordination points.
|
|
13
13
|
#
|
|
14
14
|
# Matches join/value on Thread instances whose receiver_constant is
|
|
15
15
|
# 'Thread' but whose receiver_source is not the bare literal 'Thread'.
|
|
@@ -20,17 +20,19 @@ module FiberAudit
|
|
|
20
20
|
# and workspace-shadowed Thread (checked via workspace or
|
|
21
21
|
# workspace.semantic_index resolve_constant seam). Adapter errors from
|
|
22
22
|
# those seams are swallowed — they never raise.
|
|
23
|
+
#
|
|
24
|
+
# Advisory rule: uses advisory_severity (no context ceiling), default :low.
|
|
23
25
|
class ThreadJoin < Base
|
|
24
26
|
id 'FA1002'
|
|
25
|
-
severity :
|
|
27
|
+
severity :low
|
|
26
28
|
confidence :high
|
|
27
|
-
description '
|
|
29
|
+
description 'Thread waits require scheduler block/unblock cooperation'
|
|
28
30
|
|
|
29
31
|
TITLE = 'Thread wait'
|
|
30
32
|
CATEGORY = :synchronization
|
|
31
|
-
MESSAGE = '
|
|
32
|
-
REMEDIATION = '
|
|
33
|
-
'or move the
|
|
33
|
+
MESSAGE = 'Thread#join/value requires scheduler block/unblock cooperation in a non-blocking Fiber.'
|
|
34
|
+
REMEDIATION = 'Verify scheduler coordination and runtime progress, ' \
|
|
35
|
+
'or move the wait outside the fiber-scheduled path.'
|
|
34
36
|
TARGET_METHODS = OperationVocabulary::FA1002_METHODS
|
|
35
37
|
CANONICAL_OPS = OperationVocabulary::FA1002_OPERATIONS
|
|
36
38
|
DIRECT_CLASS_SOURCE = 'Thread'
|
|
@@ -73,7 +75,7 @@ module FiberAudit
|
|
|
73
75
|
def build_finding(site)
|
|
74
76
|
loc = site.location
|
|
75
77
|
op = "Thread.#{site.method_name}"
|
|
76
|
-
sev =
|
|
78
|
+
sev = advisory_severity(self.class.severity)
|
|
77
79
|
conf = site.receiver_source == 'Thread.current' ? :high : site.confidence
|
|
78
80
|
|
|
79
81
|
Finding.new(
|
data/lib/fiber_audit/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fiber_audit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- FiberAudit Contributors
|
|
@@ -95,6 +95,7 @@ files:
|
|
|
95
95
|
- lib/fiber_audit/runtime/redactor.rb
|
|
96
96
|
- lib/fiber_audit/runtime/sampler.rb
|
|
97
97
|
- lib/fiber_audit/runtime/scheduler_observer.rb
|
|
98
|
+
- lib/fiber_audit/runtime/scheduler_snapshot.rb
|
|
98
99
|
- lib/fiber_audit/runtime/session.rb
|
|
99
100
|
- lib/fiber_audit/runtime/supervisor.rb
|
|
100
101
|
- lib/fiber_audit/runtime/validation.rb
|