Skip to content

Commit 8b62761

Browse files
committed
Rule SIG31-C
1 parent 437d781 commit 8b62761

File tree

8 files changed

+96
-10
lines changed

8 files changed

+96
-10
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* @precision very-high
77
* @problem.severity error
88
* @tags external/cert/id/sig30-c
9+
* correctness
10+
* security
911
* external/cert/obligation/rule
1012
*/
1113

@@ -22,7 +24,7 @@ class AsyncSafeVariableAccess extends VariableAccess {
2224
AsyncSafeVariableAccess() {
2325
this.getTarget() instanceof StackVariable
2426
or
25-
this.getTarget().getType().hasName("volatile sig_atomic_t") and // TODO search without "volatile"
27+
this.getType().hasName("volatile sig_atomic_t") and // TODO search without "volatile"
2628
this.isModified() and
2729
this.getTarget().isVolatile()
2830
}

c/cert/src/rules/SIG31-C/DoNotAccessSharedObjectsInSignalHandlers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ CWE-828 = SIG31-C + non-async-safe things besides shared objects.
176176
177177
## Implementation notes
178178
179-
None
179+
The implementation does not verify the correct usage of `atomic_is_lock_free`.
180180
181181
## References
182182

c/cert/src/rules/SIG31-C/DoNotAccessSharedObjectsInSignalHandlers.ql

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,42 @@
66
* @precision very-high
77
* @problem.severity error
88
* @tags external/cert/id/sig31-c
9+
* correctness
10+
* security
911
* external/cert/obligation/rule
1012
*/
1113

1214
import cpp
1315
import codingstandards.c.cert
16+
import codingstandards.c.Signal
1417

15-
from
18+
/**
19+
* Does not an access an external variable except
20+
* to assign a value to a volatile static variable of sig_atomic_t type
21+
*/
22+
class UnsafeSharedVariableAccess extends VariableAccess {
23+
UnsafeSharedVariableAccess() {
24+
// static or thread local storage duration
25+
(
26+
this.getTarget() instanceof StaticStorageDurationVariable or
27+
this.getTarget().isThreadLocal()
28+
) and
29+
// excluding `volatile sig_atomic_t` type
30+
not (
31+
this.getType().hasName("volatile sig_atomic_t") and // TODO search without "volatile"
32+
this.getTarget().isVolatile()
33+
) and //excluding lock-free atomic objects
34+
not exists(MacroInvocation mi, VariableAccess va |
35+
mi.getMacroName() = "atomic_is_lock_free" and
36+
mi.getExpr().getChild(0) = va.getEnclosingElement*() and
37+
va.getTarget() = this.getTarget()
38+
)
39+
}
40+
}
41+
42+
from UnsafeSharedVariableAccess va, SignalHandler handler
1643
where
17-
not isExcluded(x, SignalHandlersPackage::doNotAccessSharedObjectsInSignalHandlersQuery()) and
18-
select
44+
not isExcluded(va, SignalHandlersPackage::doNotAccessSharedObjectsInSignalHandlersQuery()) and
45+
handler = va.getEnclosingFunction()
46+
select va, "Shared object access within a $@ can lead to undefined behavior.",
47+
handler.getRegistration(), "signal handler"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:11:3:11:18 | call to log_local_unsafe | Asyncronous-unsafe function calls within a $@ can lead to undefined behavior. | test.c:17:7:17:12 | call to signal | signal handler |
2+
| test.c:12:3:12:6 | call to free | Asyncronous-unsafe function calls within a $@ can lead to undefined behavior. | test.c:17:7:17:12 | call to signal | signal handler |
3+
| test.c:48:3:48:17 | call to siglongjmp | Asyncronous-unsafe function calls within a $@ can lead to undefined behavior. | test.c:52:7:52:12 | call to signal | signal handler |
4+
| test.c:78:7:78:11 | call to raise | Asyncronous-unsafe function calls within a $@ can lead to undefined behavior. | test.c:93:7:93:12 | call to signal | signal handler |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
No expected results have yet been specified
1+
| test.c:7:10:7:16 | err_msg | Shared object access within a $@ can lead to undefined behavior. | test.c:11:3:11:8 | call to signal | signal handler |

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <signal.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
char *err_msg;
6+
void handler(int signum) {
7+
strcpy(err_msg, "SIGINT encountered."); // NON_COMPLIANT
8+
}
9+
10+
void f1(void) {
11+
signal(SIGINT, handler);
12+
// ...
13+
}
14+
15+
volatile sig_atomic_t e_flag1 = 0;
16+
void handler2(int signum) {
17+
e_flag1 = 1; // COMPLIANT
18+
}
19+
20+
void f2(void) {
21+
signal(SIGINT, handler2);
22+
// ...
23+
}
24+
25+
#include <stdatomic.h>
26+
27+
atomic_int e_flag3 = ATOMIC_VAR_INIT(0);
28+
void handler3(int signum) {
29+
e_flag3 = 1; // COMPLIANT
30+
}
31+
32+
void f3(void) {
33+
if (!atomic_is_lock_free(&e_flag3)) {
34+
// ...
35+
}
36+
37+
if (signal(SIGINT, handler3) == SIG_ERR) {
38+
// ...
39+
}
40+
}

c/common/test/includes/standard-library/stdatomic.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
#define atomic_load(a) 0
44
#define atomic_load_explicit(a, b)
55
#define atomic_store(a, b) 0
6-
#define atomic_store_explicit(a,b,c) 0
7-
#define ATOMIC_VAR_INIT(value) (value)
6+
#define atomic_store_explicit(a, b, c) 0
7+
#define ATOMIC_VAR_INIT(value) (value)
8+
#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
9+
typedef _Atomic(int) atomic_int;

rule_packages/c/SignalHandlers.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
"precision": "very-high",
1313
"severity": "error",
1414
"short_name": "CallOnlyAsyncSafeFunctionsWithinSignalHandlers",
15-
"tags": []
15+
"tags": [
16+
"correctness",
17+
"security"
18+
]
1619
}
1720
],
1821
"title": "Call only asynchronous-safe functions within signal handlers"
@@ -29,7 +32,13 @@
2932
"precision": "very-high",
3033
"severity": "error",
3134
"short_name": "DoNotAccessSharedObjectsInSignalHandlers",
32-
"tags": []
35+
"tags": [
36+
"correctness",
37+
"security"
38+
],
39+
"implementation_scope": {
40+
"description": "The implementation does not verify the correct usage of `atomic_is_lock_free`."
41+
}
3342
}
3443
],
3544
"title": "Do not access shared objects in signal handlers"

0 commit comments

Comments
 (0)