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

Compare with Current View Page History

« Previous Version 77 Next »

The C11 Standard [ISO/IEC 9899:2011] introduced a new term: temporary lifetime. Modifying an object with temporary lifetime results in undefined behavior (see subclause 6.2.4, paragraph 8).

A non-lvalue expression with structure or union type, where the structure or union contains a member with array type (including, recursively, members of all contained structures and unions) refers to an object with automatic storage duration and temporary lifetime. Its lifetime begins when the expression is evaluated and its initial value is the value of the expression. Its lifetime ends when the evaluation of the containing full expression or full declarator ends. Any attempt to modify an object with temporary lifetime results in undefined behavior.

This definition differs from the C99 Standard (which defines modifying the result of a function call or accessing it after the next sequence point as undefined behavior) because a temporary object's lifetime ends when the evaluation containing the full expression or full declarator ends, so the result of a function call can be accessed. This extension to the lifetime of a temporary also removes a quiet change to C90 and improves compatibility with C++. 

C functions may not return entire arrays; however, functions can return a pointer to an array and return structs or unions that contain arrays. Consequently, if a function call's return value contains an array, that array should never be modified within the expression containing the function call. Do not access an array returned by a function after the next sequence point or after the evaluation of the containing full expression or full declarator ends.

Nonompliant Code Example

This noncompliant code example is C11 compliant; however, it is noncompliant C99 code having undefined behavior because the sequence point preceding the call to printf() comes between the call and the access by printf() of the string in the returned object:

#include <stdio.h>

struct X { char a[8]; };

struct X salutation() {
  struct X result = { "Hello" };
  return result;
}

struct X addressee() {
  struct X result = { "world" };
  return result;
}

int main(void) {
  printf("%s, %s!\n", salutation().a, addressee().a);
  return 0;
}

Compliant Solution

This compliant solution stores the structures returned by the call to addressee() before calling the printf() function:

#include <stdio.h>

struct X { char a[8]; };
 
struct X salutation() {
  struct X result = { "Hello" };
  return result;
}

struct X addressee(void) {
  struct X result = { "world" };
  return result;
}

int main(void) {
  struct X my_salutation = salutation();
  struct X my_addressee = addressee();
 
  printf("%s, %s!\n", my_salutation.a, my_addressee.a);
  return 0;
}

Noncompliant Code Example

The following noncompliant code attempts to retrieve an array and increment the first value from a struct that is returned by a function call. Because the array is being modified, the attempted retrieval results in undefined behavior.

#include <stdio.h>

struct X { int a[6]; };

struct X addressee(void) {
  struct X result = { 1, 2, 3, 4, 5, 6 };
  return result;
}

int main(void) {
  printf("%x", ++(addressee().a[0]));
  return 0;
}

Compliant Solution

This compliant solution stores the structure returned by the call to addressee() as my_x before calling the printf() function:

#include <stdio.h>

struct X { int a[6]; };

struct X addressee(void) {
  struct X result = { 1, 2, 3, 4, 5, 6 };
  return result;
}

int main(void) {
  struct X my_x = addressee();
  printf("%x", ++(my_x.a[0]));
  return 0;
}

Risk Assessment

Attempting modify an array or access it after its lifetime expires may result in erroneous program behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP35-C

low

probable

medium

P4

L3

Automated Detection

Tool

Version

Checker

Description

GCC

4.3.5

 

Can detect violations of this rule when the -Wall flag is used

Splint

3.1.1

 

 

Related Vulnerabilities

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

Related Guidelines

ISO/IEC TR 24772:2013Dangling References to Stack Frames [DCM]
Side-effects and Order of Evaluation [SAM]

Bibliography

[ISO/IEC 9899:2011]Subclause 6.2.4, "Storage Durations of Objects"

 


 

  • No labels