...
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 |
...