Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In this noncompliant example, exit code is written for every instance in which the function can terminate prematurely. Notice how failing to allocate obj3 obj2 produces a memory leak and fails to close the opened file.

Code Block
bgColor#FFCCCC
typedef struct object {   // A generic struct -- The contents don't matter
  int propertyA, propertyB, propertyC;
} object_t;


int do_something(void){
  FILE *fin;
  object_t *obj1, *obj2, *obj3;
  
  fin = fopen("some_file", "r");
  if (fin == NULL){
    return -1;
  }

  obj1 = malloc(sizeof(object_t));
  if (obj1 == NULL){
    fclose(fin);
    return -1;
  }

  obj2 = malloc(sizeof(object_t));
  if (obj2 == NULL){
    fclose(fin);
    free(obj1);
    return -1;
  }

  obj3 = malloc(sizeof(object_t));
  if (obj3 == NULL){
    fclose(fin);
    free(obj2);
    return -1; // Forgot to free obj1 -- Memory leak!!
  }

  // ... more code ...
}

This is also just a small example; in much larger examples, errors like this would be even harder to detect.

...

Code Block
bgColor#CCCCFF
// ... assume the same struct as above ...

int do_something(void){
  FILE *fin;
  object_t *obj1, *obj2, *obj3;  

  fin = fopen("some_file", "r");
  if (fin == NULL){
    goto FAIL_FIN;
  }

  obj1 = malloc(sizeof(object_t));
  if (obj1 == NULL){
    goto FAIL_OBJ1;
  }

  obj2 = malloc(sizeof(object_t));
  if (obj2 == NULL){
    goto FAIL_OBJ2;
  }

  obj3 = malloc(sizeof(object_t));
  if (obj3 == NULL){
    goto FAIL_OBJ3;
  }


  // ... more code ...


SUCCESS:     // Return normally Free everything and return normally
  fclose(fin);
  free(obj1);
  free(obj2);
  return 0;

FAIL_OBJ3OBJ2:   // Otherwise, free objects in order
  free(obj2);

FAIL_OBJ2:
  free(obj1);

FAIL_OBJ1:
  fclose(fin);

FAIL_FIN:
  return -1;
}

...

Wiki Markup
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.20.3, "Memory management functions"
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.19.5, "File access functions"
\[[Seacord 05|AA. C References#Seacord 05]\] Chapter 4, "Dynamic Memory Management"

Related Vulnerabilities

In C++, one could use this same strategy when constructing and destructing objects.