Skip to content

Commit e7dec51

Browse files
committed
Implement rule SIG34-C
1 parent 2095248 commit e7dec51

File tree

5 files changed

+48
-4
lines changed

5 files changed

+48
-4
lines changed

c/cert/src/rules/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class ApplicationAsyncSafeFunction extends AsyncSafeFunction {
100100
class AsyncUnsafeRaiseCall extends FunctionCall {
101101
AsyncUnsafeRaiseCall() {
102102
this.getTarget().hasGlobalName("raise") and
103-
exists(SignalHandler handler | handler = this.getEnclosingFunction() |
103+
exists(SignalHandler handler |
104+
handler = this.getEnclosingFunction() and
104105
not handler.getRegistration().getArgument(0).getValue() = this.getArgument(0).getValue() and
105106
not DataFlow::localFlow(DataFlow::parameterNode(handler.getParameter(0)),
106107
DataFlow::exprNode(this.getArgument(0)))

c/cert/src/rules/SIG34-C/DoNotCallSignalFromInterruptibleSignalHandlers.ql

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111

1212
import cpp
1313
import codingstandards.c.cert
14+
import codingstandards.c.Signal
1415

15-
from
16+
from FunctionCall x
1617
where
1718
not isExcluded(x, SignalHandlersPackage::doNotCallSignalFromInterruptibleSignalHandlersQuery()) and
18-
select
19+
x = any(SignalHandler handler).getReassertingCall()
20+
select x,
21+
"Reasserting handler bindings introduces a race condition on nonpersistent platforms and is redundant otherwise."
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
No expected results have yet been specified
1+
| test.c:4:7:4:12 | call to signal | Reasserting handler bindings introduces a race condition on nonpersistent platforms and is redundant otherwise. |
2+
| test.c:17:7:17:12 | call to signal | Reasserting handler bindings introduces a race condition on nonpersistent platforms and is redundant otherwise. |

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <signal.h>
2+
3+
void handler1(int signum) {
4+
if (signal(signum, handler1) == SIG_ERR) // NON_COMPLIANT
5+
{
6+
//...
7+
}
8+
}
9+
10+
void f1(void) {
11+
if (signal(SIGUSR1, handler1) == SIG_ERR) {
12+
// ...
13+
}
14+
}
15+
16+
void handler2(int signum) {
17+
if (signal(SIGUSR1, handler2) == SIG_ERR) // NON_COMPLIANT
18+
{
19+
//...
20+
}
21+
}
22+
23+
void f2(void) {
24+
if (signal(SIGUSR1, handler2) == SIG_ERR) {
25+
// ...
26+
}
27+
}

c/common/src/codingstandards/c/Signal.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import cpp
2+
import semmle.code.cpp.dataflow.DataFlow
23

34
/**
45
* A call to function `signal`
@@ -19,6 +20,17 @@ class SignalHandler extends Function {
1920
}
2021

2122
SignalCall getRegistration() { result = registration }
23+
24+
FunctionCall getReassertingCall() {
25+
result.getTarget().hasGlobalName("signal") and
26+
this = result.getEnclosingFunction() and
27+
(
28+
this.getRegistration().getArgument(0).getValue() = result.getArgument(0).getValue()
29+
or
30+
DataFlow::localFlow(DataFlow::parameterNode(this.getParameter(0)),
31+
DataFlow::exprNode(result.getArgument(0)))
32+
)
33+
}
2234
}
2335

2436
/**

0 commit comments

Comments
 (0)