Comparing a function pointer to a value that is not a null function pointer of the same type shall be diagnosed because this typically indicates programmer error and can result in unexpected behavior. Implicit comparisons shall be diagnosed as well.
Noncompliant Code Example
In this noncompliant code example, the addresses of the POSIX ® functions getuid
and geteuid
are compared for equality to 0. Since the address of no function is null the first subexpression will always evaluate to false (zero) while the second subexpression always to true (non-zero). Thus, the entire expression will always evaluate to true, leading to a potential security vulnerability.
/* First the options that are only allowed for root */ if (getuid == 0 || geteuid != 0) { /* ... */ }
Noncompliant Code Example
In this noncompliant code example, the function pointers getuid
and geteuid
are compared to 0.
This noncompliant code example is from an actual vulnerability (VU#837857) discovered in some versions of the X Window System server. The vulnerability exists because the programmer neglected to provide the open and close parentheses following the geteuid()
function identifier. As a result, the geteuid
token returns the address of the function, which is never equal to zero. As a result, the or
condition of this if
statement is always true and access is provided to the protected block for all users. Many compilers issue a warning noting such pointless expressions. Therefore, this coding error is normally detected by adherence to MSC00-C. Compile cleanly at high warning levels.
/* First the options that are only allowed for root */ if (getuid() == 0 || geteuid != 0) { /* ... */ }
Compliant Solution
The solution is to provide the open and close parentheses following the geteuid
token so that the function is properly invoked.
/* First the options that are only allowed for root */ if (getuid() == 0 || geteuid() != 0) { /* ... */ }
Compliant Solution
A function pointer can be compared to a null function pointer of the same type.
/* First the options that are only allowed for root */ if (getuid == (uid_t(*)(void))0 || geteuid != (uid_t(*)(void))0) { /* ... */ }
This code should not be diagnosed by an analyzer.
Noncompliant Code Example
In this noncompliant code example, the function pointer do_xyz
is implicitly compared unequal to 0.
int do_xyz(void); if (do_xyz) { /* handle error */ }
Compliant Solution
In this compliant solution, the function do_xyz()
is invoked and the return value is compared to 0.
int do_xyz(void); if (do_xyz()) { /* handle error */ }
Risk Assessment
Errors of omission can result in unintended program flow.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
MSC02-C |
low |
likely |
medium |
P6 |
L2 |
Automated Detection
The Coverity Prevent Version 5.0 BAD_COMPARE checker can detect the specific instance where the address of a function is compared against 0, such as in the case of geteuid
versus getuid()
in the Implementation-Specific Details.
The LDRA tool suite Version 7.6.0 can detect violations of this recommendation???
GCC Compiler Version 4.4.0 can detect violations of this recommendation when the -Wall
flag is used.
Klocwork Version 8.0.4.16 can detect violations of this rule with the EFFECT checkers???
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C++ Secure Coding Standard as EXP16-CPP. Avoid errors of omission.
References
[[Hatton 95]] Section 2.7.2, "Errors of omission and addition"
[[ISO/IEC PDTR 24772]] "KOA Likely Incorrect Expressions"
[[MITRE 07]] CWE ID 482, "Comparing instead of Assigning," CWE ID 480, "Use of Incorrect Operator"