Skip to content

Commit abe3837

Browse files
committed
Inline precededBySync
1 parent c252ec0 commit abe3837

File tree

2 files changed

+18
-38
lines changed

2 files changed

+18
-38
lines changed

go/ql/src/InconsistentCode/UnhandledCloseWritableHandle.ql

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,25 @@ predicate isWritableFileHandle(DataFlow::Node source, DataFlow::CallNode call) {
9090
/**
9191
* Holds if `os.File.Close` is called on `sink`.
9292
*/
93-
predicate isCloseSink(DataFlow::Node sink, DataFlow::CallNode call) {
93+
predicate isCloseSink(DataFlow::Node sink, DataFlow::CallNode closeCall) {
9494
// find calls to the os.File.Close function
95-
call = any(CloseFileFun f).getACall() and
96-
// that are deferred
97-
unhandledCall(call) and
95+
closeCall = any(CloseFileFun f).getACall() and
96+
// that are unhandled
97+
unhandledCall(closeCall) and
9898
// where the function is called on the sink
99-
call.getReceiver() = sink
99+
closeCall.getReceiver() = sink and
100+
// and check that it is not dominated by a call to `os.File.Sync`.
101+
not exists(IR::Instruction syncInstr, DataFlow::Node syncReceiver, DataFlow::CallNode syncCall |
102+
// match the instruction corresponding to an `os.File.Sync` call with the predecessor
103+
syncCall.asInstruction() = syncInstr and
104+
// check that the call to `os.File.Sync` is handled
105+
isHandledSync(syncReceiver, syncCall) and
106+
// find a predecessor to `closeCall` in the control flow graph which dominates the call to
107+
// `os.File.Close`
108+
syncInstr.dominatesNode(closeCall.asInstruction()) and
109+
// check that `os.File.Sync` is called on the same object as `os.File.Close`
110+
exists(DataFlow::SsaNode ssa | ssa.getAUse() = sink and ssa.getAUse() = syncReceiver)
111+
)
100112
}
101113

102114
/**
@@ -124,25 +136,6 @@ class UnhandledFileCloseDataFlowConfiguration extends DataFlow::Configuration {
124136
override predicate isSink(DataFlow::Node sink) { isCloseSink(sink, _) }
125137
}
126138

127-
/**
128-
* Holds if a `node` is preceded by a call to `os.File.Sync`.
129-
*/
130-
predicate precededBySync(DataFlow::Node closeReceiver, DataFlow::CallNode closeCall) {
131-
// using the control flow graph, try to find a call to a handled call to `os.File.Sync`
132-
// which precedes `closeCall`.
133-
exists(IR::Instruction syncInstr, DataFlow::Node syncReceiver, DataFlow::CallNode syncCall |
134-
// match the instruction corresponding to an `os.File.Sync` call with the predecessor
135-
syncCall.asInstruction() = syncInstr and
136-
// check that the call to `os.File.Sync` is handled
137-
isHandledSync(syncReceiver, syncCall) and
138-
// find a predecessor to `closeCall` in the control flow graph which dominates the call to
139-
// `os.File.Close`
140-
syncInstr.dominatesNode(closeCall.asInstruction()) and
141-
// check that `os.File.Sync` is called on the same object as `os.File.Close`
142-
exists(DataFlow::SsaNode ssa | ssa.getAUse() = closeReceiver and ssa.getAUse() = syncReceiver)
143-
)
144-
}
145-
146139
from
147140
UnhandledFileCloseDataFlowConfiguration cfg, DataFlow::PathNode source,
148141
DataFlow::CallNode openCall, DataFlow::PathNode sink, DataFlow::CallNode closeCall
@@ -152,10 +145,7 @@ where
152145
cfg.hasFlowPath(source, sink) and
153146
isWritableFileHandle(source.getNode(), openCall) and
154147
// get the `CallNode` corresponding to the sink
155-
isCloseSink(sink.getNode(), closeCall) and
156-
// check that the call to `os.File.Close` is not preceded by a checked call to
157-
// `os.File.Sync`
158-
not precededBySync(sink.getNode(), closeCall)
148+
isCloseSink(sink.getNode(), closeCall)
159149
select sink, source, sink,
160150
"File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly.",
161151
openCall, openCall.toString()

go/ql/test/query-tests/InconsistentCode/UnhandledCloseWritableHandle/UnhandledCloseWritableHandle.expected

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ edges
22
| tests.go:9:2:9:74 | ... := ...[0] : pointer type | tests.go:10:9:10:9 | f : pointer type |
33
| tests.go:10:9:10:9 | f : pointer type | tests.go:43:5:43:38 | ... := ...[0] : pointer type |
44
| tests.go:10:9:10:9 | f : pointer type | tests.go:60:5:60:38 | ... := ...[0] : pointer type |
5-
| tests.go:10:9:10:9 | f : pointer type | tests.go:86:5:86:38 | ... := ...[0] : pointer type |
6-
| tests.go:10:9:10:9 | f : pointer type | tests.go:96:5:96:38 | ... := ...[0] : pointer type |
75
| tests.go:10:9:10:9 | f : pointer type | tests.go:108:5:108:38 | ... := ...[0] : pointer type |
86
| tests.go:10:9:10:9 | f : pointer type | tests.go:124:5:124:38 | ... := ...[0] : pointer type |
97
| tests.go:18:2:18:69 | return statement[0] : pointer type | tests.go:53:5:53:42 | ... := ...[0] : pointer type |
@@ -21,9 +19,6 @@ edges
2119
| tests.go:55:29:55:29 | f : pointer type | tests.go:25:32:25:32 | definition of f : pointer type |
2220
| tests.go:60:5:60:38 | ... := ...[0] : pointer type | tests.go:62:3:62:3 | f |
2321
| tests.go:70:5:70:42 | ... := ...[0] : pointer type | tests.go:72:3:72:3 | f |
24-
| tests.go:86:5:86:38 | ... := ...[0] : pointer type | tests.go:89:4:89:4 | f |
25-
| tests.go:86:5:86:38 | ... := ...[0] : pointer type | tests.go:91:3:91:3 | f |
26-
| tests.go:96:5:96:38 | ... := ...[0] : pointer type | tests.go:99:9:99:9 | f |
2722
| tests.go:108:5:108:38 | ... := ...[0] : pointer type | tests.go:110:9:110:9 | f |
2823
| tests.go:124:5:124:38 | ... := ...[0] : pointer type | tests.go:128:3:128:3 | f |
2924
nodes
@@ -45,11 +40,6 @@ nodes
4540
| tests.go:62:3:62:3 | f | semmle.label | f |
4641
| tests.go:70:5:70:42 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |
4742
| tests.go:72:3:72:3 | f | semmle.label | f |
48-
| tests.go:86:5:86:38 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |
49-
| tests.go:89:4:89:4 | f | semmle.label | f |
50-
| tests.go:91:3:91:3 | f | semmle.label | f |
51-
| tests.go:96:5:96:38 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |
52-
| tests.go:99:9:99:9 | f | semmle.label | f |
5343
| tests.go:108:5:108:38 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |
5444
| tests.go:110:9:110:9 | f | semmle.label | f |
5545
| tests.go:124:5:124:38 | ... := ...[0] : pointer type | semmle.label | ... := ...[0] : pointer type |

0 commit comments

Comments
 (0)