You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

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 function pointers getuid and geteuid are compared to 0.

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

/* First the options that are only allowed for root */
if (getuid() == 0 || geteuid != 0) {
  /* ... */
}

Implementation-Specific Details

This error can often be detected through the analysis of compiler warnings. For example, when this code is compiled with some versions of the GCC compiler,

#include <unistd.h>
#include <stdlib.h>

int main(void) {
  geteuid ? exit(0) : exit(1);
}

the following warning will be generated:

example.c: In function 'main':
example.c:6: warning: the address of 'geteuid', will always
  evaluate as 'true'

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) {
  /* ... */
}

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

Compass/ROSE could detect violations of this recommendation by identifying any assignment expression as the top-level expression in an if or while statement. To identify the geteuid example, ROSE should search for:

  • any 'address of function' expression, where the address is implicit (eg the function is not preceded by &).
  • The function expression is used in any expression EXCEPT:
  • as an argument to another function (signal() for instance)
  • as an assignment to a function pointer

Klocwork Version 8.0.4.16 can detect violations of this rule with the ASSIGCOND.BOOL, ASSIGCOND.CALL, ASSIGCOND.GEN, and 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"

  • No labels