Skip to content

Commit 785f29b

Browse files
committed
Covers test case proposed during the review
1 parent d16077d commit 785f29b

File tree

3 files changed

+49
-17
lines changed

3 files changed

+49
-17
lines changed

c/cert/src/rules/ERR32-C/DoNotRelyOnIndeterminateValuesOfErrno.ql

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,22 @@ class SignalCheckOperation extends EqualityOperation, GuardCondition {
3737
)
3838
}
3939

40+
ControlFlowNode getCheckedSuccessor() {
41+
result != errorSuccessor and result = this.getASuccessor()
42+
}
43+
4044
ControlFlowNode getErrorSuccessor() { result = errorSuccessor }
4145
}
4246

4347
/**
4448
* Models signal handlers that call signal() and return
4549
*/
4650
class SignalCallingHandler extends Function {
47-
SignalCall sh;
51+
SignalCall registration;
4852

4953
SignalCallingHandler() {
5054
// is a signal handler
51-
this = sh.getArgument(1).(FunctionAccess).getTarget() and
55+
this = registration.getArgument(1).(FunctionAccess).getTarget() and
5256
// calls signal() on the handled signal
5357
exists(SignalCall sCall |
5458
sCall.getEnclosingFunction() = this and
@@ -63,18 +67,35 @@ class SignalCallingHandler extends Function {
6367
)
6468
}
6569

66-
SignalCall getHandler() { result = sh }
70+
SignalCall getCall() { result = registration }
71+
}
72+
73+
/**
74+
* CFG nodes preceeding `ErrnoRead`
75+
*/
76+
ControlFlowNode preceedErrnoRead(ErrnoRead er) {
77+
result = er
78+
or
79+
exists(ControlFlowNode mid |
80+
result = mid.getAPredecessor() and
81+
mid = preceedErrnoRead(er) and
82+
// stop recursion on calls to `abort` and `_Exit`
83+
not result.(FunctionCall).getTarget().hasGlobalName(["abort", "_Exit"]) and
84+
// stop recursion on successful `SignalCheckOperation`
85+
not result = any(SignalCheckOperation o).getCheckedSuccessor()
86+
)
6787
}
6888

69-
from ErrnoRead errno, SignalCall h
89+
from ErrnoRead errno, SignalCall signal
7090
where
7191
not isExcluded(errno, Contracts5Package::doNotRelyOnIndeterminateValuesOfErrnoQuery()) and
72-
exists(SignalCallingHandler sc | sc.getHandler() = h |
73-
// errno read in the handler
74-
sc.calls*(errno.getEnclosingFunction())
92+
exists(SignalCallingHandler handler |
93+
// errno read after the handler returns
94+
handler.getCall() = signal
7595
or
76-
// errno is read after the handle returns
77-
sc.getHandler() = h and
78-
errno.getAPredecessor+() = h
96+
// errno read inside the handler
97+
signal.getEnclosingFunction() = handler
98+
|
99+
signal = preceedErrnoRead(errno)
79100
)
80-
select errno, "`errno` has indeterminate value after this $@.", h, h.toString()
101+
select errno, "`errno` has indeterminate value after this $@.", signal, signal.toString()
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
| test.c:12:5:12:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:35:21:35:26 | call to signal | call to signal |
2-
| test.c:37:5:37:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:35:21:35:26 | call to signal | call to signal |
3-
| test.c:42:5:42:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:35:21:35:26 | call to signal | call to signal |
4-
| test.c:51:5:51:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:35:21:35:26 | call to signal | call to signal |
5-
| test.c:51:5:51:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:45:17:45:22 | call to signal | call to signal |
1+
| test.c:12:5:12:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:10:21:10:26 | call to signal | call to signal |
2+
| test.c:39:5:39:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:35:21:35:26 | call to signal | call to signal |
3+
| test.c:46:5:46:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:44:21:44:26 | call to signal | call to signal |
4+
| test.c:62:5:62:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:54:17:54:22 | call to signal | call to signal |
5+
| test.c:62:5:62:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:58:17:58:22 | call to signal | call to signal |

c/cert/test/rules/ERR32-C/test.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ void handler4(int signum) {
3131
}
3232
}
3333

34+
void handler5(int signum) {
35+
pfv old_handler = signal(signum, SIG_DFL);
36+
if (old_handler != SIG_ERR) {
37+
perror(""); // COMPLIANT
38+
} else {
39+
perror(""); // NON_COMPLIANT
40+
}
41+
}
42+
3443
int main(void) {
3544
pfv old_handler = signal(SIGINT, handler1);
3645
if (old_handler == SIG_ERR) {
@@ -39,13 +48,15 @@ int main(void) {
3948

4049
old_handler = signal(SIGINT, handler2);
4150
if (old_handler == SIG_ERR) {
42-
perror(""); // NON_COMPLIANT
51+
perror(""); // COMPLIANT
4352
}
4453

4554
old_handler = signal(SIGINT, handler3);
4655

4756
old_handler = signal(SIGINT, handler4);
4857

58+
old_handler = signal(SIGINT, handler5);
59+
4960
FILE *fp = fopen("something", "r");
5061
if (fp == NULL) {
5162
perror("Error: "); // NON_COMPLIANT

0 commit comments

Comments
 (0)