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

Compare with Current View Page History

« Previous Version 2 Next »

According to the C++ Standard, [stmt.return], paragraph 2 [ISO/IEC 14882-2014]: 

Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

A value-returning function must return a value from all code paths, or will otherwise result in undefined behavior. This includes returning through less common code paths, such as from a function try block, as explained in the C++ Standard, [except.handle], paragraph 15:

Flowing off the end of a function-try-block is equivalent to a return with no value; this results in undefined behavior in a value-returning function (6.6.3).

Noncompliant Code Example

In this noncompliant code example, the programmer forgot to return the input value for positive input, and so not all code paths return a value:

int absolute_value(int a) {
  if (a < 0) {
    return -a;
  }
}

Compliant Solution

In this compliant solution, all code paths now return a value:

int absolute_value(int a) {
  if (a < 0) {
    return -a;
  }
  return a;
}

Noncompliant Code Example

In this noncompliant code example, the function try block handler does not return a value, resulting in undefined behavior when an exception is thrown:

#include <vector>
 
size_t f(std::vector<int> &v, size_t s) try {
  v.resize(s);
  return s;
} catch (...) {
}

Compliant Solution

In this compliant solution, the exception handler of the function try block also returns a value:

#include <vector>
 
size_t f(std::vector<int> &v, size_t s) try {
  v.resize(s);
  return s;
} catch (...) {
  return 0;
}

Exceptions

MSC36-EX1: Flowing off the end of the main() function is equivalent to a return 0; statement according to the C++ Standard, [basic.start.main], paragraph 5. It does not result in undefined behavior when flowing off the end of the main() function.

MSC36-EX2: It is permissible for a control path to not return a value if that code path is never taken and a function marked [[noreturn]] is called as part of that code path, or an exception is thrown. For example:

#include <iostream>

[[noreturn]] void unreachable(const char *msg) {
  std::cout << "Unreachable code reached: " << msg << std::endl;
  std::exit(1);
}

enum E {
  One,
  Two,
  Three
};

int f(E e) {
  switch (e) {
  case One: return 1;
  case Two: return 2;
  case Three: return 3;
  }
  unreachable("Can never get here");
}

Risk Assessment

Failing to return a value from a code path in a value-returning function results in undefined behavior that might be exploited to cause data integrity violations.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC36-CPP

High

Probable

Medium

P6

L2

Automated Detection

Tool

Version

Checker

Description

    

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

  

Bibliography

[ISO/IEC 14882-2014]

6.6.3, "The return Statement"
15.3, "Handling an Exception"
3.6.1, "Main Function" 

 


  

  • No labels