...
This noncompliant code example calls setjmp()
in an assignment statement, resulting in undefined behavior.:
Code Block | ||||
---|---|---|---|---|
| ||||
jmp_buf buf; void f(void) { int i = setjmp(buf); if (i == 0) { g(); } else { /* longjmp was invoked */ } } void g(void) { /* ... */ longjmp(buf, 1); } |
...
Placing the call to setjmp()
in the if
statement and, optionally, comparing it with a constant integer removes the undefined behavior, as shown in this compliant solution.:
Code Block | ||||
---|---|---|---|---|
| ||||
jmp_buf buf; void f(void) { if (setjmp(buf) == 0) { g(); } else { /* longjmp was invoked */ } } void g(void) { /* ... */ longjmp(buf, 1); } |
...
Any attempt to invoke the longjmp()
function to transfer control to a function that has completed execution results in undefined behavior.:
Code Block | ||||
---|---|---|---|---|
| ||||
jmp_buf buf; unsigned char b[] = {0xe5, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}; int main(void) { setup(); do_stuff(); return 0; } void setup(void) { f(); } void f(void) { g(); } void g(void) { if (setjmp(buf) == 0) { printf("setjmp() invoked\n"); } else { printf("longjmp() invoked\n"); } } void do_stuff(void) { char a[8]; memcpy(a, b, 8); /* ... stuff ... */ longjmp(buf, 1); } void bad(void) { printf("Should not be called!\n"); exit(1); } |
...
In this noncompliant example, non-volatile-qualified objects local to the function that invoked the corresponding setjmp()
have indeterminate values after longjmp()
is executed if their value has been changed since the invocation of setjmp()
.:
Code Block | ||||
---|---|---|---|---|
| ||||
jmp_buf buf; void f(void) { int i = 0; if (setjmp(buf) != 0) { printf("%i\n", i); /* ... */ } i = 2; g(); } void g(void) { /* ... */ longjmp(buf, 1); } |
...
If an object local to the function that invoked setjmp()
needs to be accessed after longjmp()
returns control to the function, the object should be volatile-qualified.:
Code Block | ||||
---|---|---|---|---|
| ||||
jmp_buf buf; void f(void) { volatile int i = 0; if (setjmp(buf) != 0) { printf("%i\n", i); /* ... */ } i = 2; g(); } void g(void) { /* ... */ longjmp(buf, 1); } |
...
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC22-C | low | probable | medium | P4 | L3 |
...