Contenu principal

CERT C: Rec. API01-C

Avoid laying out strings in memory directly before sensitive data

Since R2026a

Description

Avoid laying out strings in memory directly before sensitive data1

Polyspace Implementation

The rule checker checks for Pointer immediately past string.

Examples

expand all

Issue

This issue occurs if a pointer is immediately after a character array in a structure. For example, in this code, the content of the structure foo is placed together in memory. Because the pointer *ptr is immediately after the character array str, Polyspace® reports a violation:

#define SIZE 20
struct foo(
    char str[SIZE];
    int* ptr;
)
A violation is not reported if a struct containing only a string and a pointer is stored in an array. In this case, the pointer is always stored after the string regardless of how they are positioned in the code.

Risk

If a pointer is stored immediately after a character array, any overflow of the character array overwrites the pointer. The pointer can then be used for accessing or overwriting arbitrary memory, compromising the security of the code.

Fix

Avoid placing pointers immediately after a character array. When you declare a pointer and a character array as structure fields, place the pointer before the character array.

Example — Implementation of linked list

In this example, the structure Node represent a node in a linked list. Because the structure stores a pointer immediately following a character array, Polyspace reports a violation.

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

#define MAX_STR_LEN 20

typedef struct Node {
    char data[MAX_STR_LEN]; //Noncompliant
    struct Node* next;
} Node;

Node* createNode(const char* data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (!newNode) exit(1);
    strncpy(newNode->data, data, MAX_STR_LEN - 1);
    newNode->data[MAX_STR_LEN - 1] = '\0'; // Ensure null-termination
    newNode->next = NULL;
    return newNode;
}

void append(Node** head, const char* data) {
    Node* newNode = createNode(data);
    if (!*head) {
        *head = newNode;
        return;
    }
    Node* last = *head;
    while (last->next) last = last->next;
    last->next = newNode;
}

void printList(Node* head) {
    while (head) {
        printf("%s -> ", head->data);
        head = head->next;
    }
    printf("NULL\n");
}

void freeList(Node* head) {
    Node* tmp;
    while (head) {
        tmp = head;
        head = head->next;
        free(tmp);
    }
}

int main() {
    Node* head = NULL;
    append(&head, "Hello, World!");
    append(&head, "This is a linked list");
    append(&head, "C programming");
    printList(head);
    freeList(head);
    return 0;
}

Correction

To fix the violation, store the pointer before the character array.

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

#define MAX_STR_LEN 20

typedef struct Node {
    struct Node* next;
    char data[MAX_STR_LEN]; //Compliant
} Node;

Node* createNode(const char* data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (!newNode) exit(1);
    strncpy(newNode->data, data, MAX_STR_LEN - 1);
    newNode->data[MAX_STR_LEN - 1] = '\0'; // Ensure null-termination
    newNode->next = NULL;
    return newNode;
}

void append(Node** head, const char* data) {
    Node* newNode = createNode(data);
    if (!*head) {
        *head = newNode;
        return;
    }
    Node* last = *head;
    while (last->next) last = last->next;
    last->next = newNode;
}

void printList(Node* head) {
    while (head) {
        printf("%s -> ", head->data);
        head = head->next;
    }
    printf("NULL\n");
}

void freeList(Node* head) {
    Node* tmp;
    while (head) {
        tmp = head;
        head = head->next;
        free(tmp);
    }
}

int main() {
    Node* head = NULL;
    append(&head, "Hello, World!");
    append(&head, "This is a linked list");
    append(&head, "C programming");
    printList(head);
    freeList(head);
    return 0;
}

Check Information

Group: Rec. 13. Application Programming Interfaces (API)
PQL Name: std.cert.API01_C

Version History

Introduced in R2026a


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.