Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Corrected calloc NCCE/CS to focus on only one problem.

...

Code Block
bgColor#FFCCCC
langc
#include <stdlib.h>
#include <string.h>
 
enum { SIG_DESC_SIZE = 32 };

typedef struct {
  char sig_desc[SIG_DESC_SIZE];
} signal_info;
 
void func(size_t num_of_records, size_t temp_num,
          const char *tmp2, size_t tmp2_size_bytes) {
  signal_info *start = (signal_info *)calloc(num_of_records,
                                          sizeof(signal_info));

  if (tmp2 == NULL) {
    /* Handle signal_infoerror *point/
  =} startelse +if (temp_num - 1; > num_of_records) {
    /* Handle error */
  } else if (tmp2 == NULL_size_bytes < SIG_DESC_SIZE) {
    /* Handle error */
  }

  signal_info *point = start + temp_num - 1;
  memcpy(point->sig_desc, tmp2,  SIG_DESC_SIZE);
  point->sig_desc[SIG_DESC_SIZE) - 1] = '\0';
  /* ... */
  free(start);
}

When calloc() fails, it returns a null pointer that is assigned to start. If start is null, an attacker can provide a value for temp_num that, when scaled by sizeof(signal_info), references a writable address to which control is eventually transferred. The contents of the string referenced by tmp2 can then be used to overwrite the address, resulting in an arbitrary code execution vulnerability.

...

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
#include <string.h>

enum { SIG_DESC_SIZE = 32 };

typedef struct {
  char sig_desc[SIG_DESC_SIZE];
} signal_info;
 
void func(size_t num_of_records, size_t temp_num,
          const char *tmp2) {
  signal_info *point;, size_t tmp2_size_bytes) {
  signal_info *start = (signal_info *)calloc(num_of_records,
                                           sizeof(signal_info));
  if (start == NULL) {
    /* Handle allocation error */
  } else if (tmp2 == NULL) {
    /* Handle error */
  sizeof(signal_info));
 } else if (start == NULLtemp_num > num_of_records) {
    /* Handle allocation error */
  } else if (tmp2 == NULL_size_bytes < SIG_DESC_SIZE) {
    /* Handle error */
  } 

  signal_info *point = start + temp_num - 1; 
  memcpy(point->sig_desc, tmp2, SIG_DESC_SIZE);
  point->sig_desc[ SIG_DESC_SIZE - 1] = '\0';
  /* ... */
  free(start);
}

Noncompliant Code Example (realloc())

...