...
This noncompliant code example implements an idle task that continuously executes a loop without executing any instructions within the loop. An optimizing compiler could remove the while loop in the example.
Code Block | ||
---|---|---|
| ||
public int mainnop(void) { while (1true) { } } |
Compliant Solution (
...
sleep()
To avoid optimizing out of the loop, this compliant solution uses instructions that give up the CPU within the while loop. On POSIX platform, sleep(3)
can be used. Other platforms might have equivalent functions.
Code Block | ||
---|---|---|
| ||
int main(void) {
while(1) {
sleep(DURATION);
}
}
|
Noncompliant Code Example
This noncompliant code example sets up interrupt handlers to process packets coming in from the network. It then waits for interrupts within a loop. Any interrupt causes the rcv_intr()
function to be invoked.
However, an optimizing compiler could remove the for loop in the example. This example also violates the recommendation SIG02-C. Avoid using signals to implement normal functionality.
Code Block | ||
---|---|---|
| ||
int main(void) {
/* set up buffers, signal handlers for interrupts, etc. */
/* ... */
for ( ; ; ) {
; /* let interrupt handler do all the work */
}
/* not reached */
}
void rcv_intr(int interrupt) { /* signal handler entered upon data_available interrupt */
/* ... */
get_packet(); /* read the packet */
if (packet.hdr.service == ICMP_ECHO) {
send_packet(); /* send the packet */
}
/* ... */
}
|
Compliant Solution (POSIX)
This compliant solution avoids optimizing out the loop by using instructions that give up the CPU within the for loop. On POSIX platform, sleep(3)
can be used. Other platforms might have equivalent functions.
Code Block | ||
---|---|---|
| ||
int main(void) {
/* set up buffers, signal handlers for interrupts, etc. */
/* ... */
for ( ; ; ) {
sleep(DURATION); /* let interrupt handler do all the work */
}
/* not reached */
}
void rcv_intr(int interrupt) { /* signal handler entered upon data_available interrupt */
/* ... */
get_packet(); /* read the packet */
if (packet.hdr.service == ICMP_ECHO) {
send_packet(); /* send the packet */
}
/* ... */
}
|
Exceptions
MSC01-EX0: In rare cases, use of an empty infinite loop may be unavoidable. For instance, an empty loop may be necessary on a platform that does not support sleep(3)
or an equivalent function. Another example occurs in operating system kernels. A task started before normal scheduler functionality is available may not have access to sleep(3)
or an equivalent function. In such a case, it is necessary to adopt alternative solutions that prevent an optimizing compiler from removing the empty infinite loop.
public final int DURATION=10000; // in milliseconds
public void nop() throws InterruptedException {
while (true) {
Thread.sleep(DURATION);
}
}
|
Compliant Solution (yield()
)
This compliant solution invokes Thread.yield()
, which causes the thread running this method to consistently defer to other threadsThe following solution uses a volatile variable.
Code Block | ||
---|---|---|
| ||
intpublic void mainnop(void) { volatile int true_value = 1; while (true_value) { } } |
The following solution is specific to the GCC 4.4.0 (or newer) compiler. It uses the optimize
function attribute to turn off optimization at a function level, without disabling optimization for the rest of the code.
Code Block | ||
---|---|---|
| ||
int main(void) __attribute__ ((optimize("O0"))); int main(void) { while (1) { Thread.yield(); } } |
Risk Assessment
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC01-J | low | unlikely | medium | P2 | L3 |
Related Guidelines
CERT C Secure Coding Standard: MSC40-C. Do not use an empty infinite loop
Bibliography
Wiki Markup |
---|
\[[API 2006|https://www.securecoding.cert.org/confluence/display/java/AA.+Java+References#AA.JavaReferences-API06]\] |
...