Main Content

CERT C: Rule MEM33-C

Allocate and copy structures containing a flexible array member dynamically

Description

Rule Definition

Allocate and copy structures containing a flexible array member dynamically.1

Polyspace Implementation

The rule checker checks for Misuse of structure with flexible array member.

Examples

expand all

Issue

Misuse of structure with flexible array member occurs when:

  • You define an object with a flexible array member of unknown size at compilation time.

  • You make an assignment between structures with a flexible array member without using memcpy() or a similar function.

  • You use a structure with a flexible array member as an argument to a function and pass the argument by value.

  • Your function returns a structure with a flexible array member.

A flexible array member has no array size specified and is the last element of a structure with at least two named members.

Risk

If the size of the flexible array member is not defined, it is ignored when allocating memory for the containing structure. Accessing such a structure has undefined behavior.

Fix
  • Use malloc() or a similar function to allocate memory for a structure with a flexible array member.

  • Use memcpy() or a similar function to copy a structure with a flexible array member.

  • Pass a structure with a flexible array member as a function argument by pointer.

Example - Structure Passed By Value to Function
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>


struct example_struct
{
    size_t num;
    int data[];
};

extern void arg_by_value(struct example_struct s);

void func(void)
{
    struct example_struct *flex_struct;
    size_t i;
    size_t array_size = 4;
    /* Dynamically allocate memory for the struct */
    flex_struct = (struct example_struct *)
        malloc(sizeof(struct example_struct) + sizeof(int) * array_size);
    if (flex_struct == NULL)
    {
        /* Handle error */    
    }
    /* Initialize structure */
    flex_struct->num = array_size;
    for (i = 0; i < array_size; ++i)
    {
        flex_struct->data[i] = 0;
    }
    /* Handle structure */
	
	/* Argument passed by value. 'data' not 
	copied to passed value. */
    arg_by_value(*flex_struct);  //Noncompliant
	
    /* Free dynamically allocated memory */
    free(flex_struct);
}
        
      

In this example, flex_struct is passed by value as an argument to arg_by_value. As a result, the flexible array member data is not copied to the passed argument.

Correction — Pass Structure by Pointer to Function

To ensure that all the members of the structure are copied to the passed argument, pass flex_struct to arg_by_pointer by pointer.

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>


struct example_struct
{
    size_t num;
    int data[];
};

extern void arg_by_pointer(struct example_struct *s);

void func(void)
{
    struct example_struct *flex_struct;
    size_t i;
    size_t array_size = 4;
    /* Dynamically allocate memory for the struct */
    flex_struct = (struct example_struct *)
        malloc(sizeof(struct example_struct) + sizeof(int) * array_size);
    if (flex_struct == NULL)
    {
        /* Handler error */       
    }
    /* Initialize structure */
    flex_struct->num = array_size;
    for (i = 0; i < array_size; ++i)
    {
        flex_struct->data[i] = 0;
    }
    /* Handle structure */
	
	/* Structure passed by pointer */
    arg_by_pointer(flex_struct); 
	
    /* Free dynamically allocated memory */
    free(flex_struct);
} 

Check Information

Group: Rule 08. Memory Management (MEM)

Version History

Introduced in R2019a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.