Safeguard
Application Security•

CWE-469 Use of Pointer Subtraction to Determine Size

Subtracting two pointers only means something inside one memory chunk. CWE-469 explained with the linked list size bug and the index variable fix.

Safeguard Security Team
3 min read

CWE-469 happens when a product subtracts one pointer from another to determine a size, but the calculation can be wrong if the pointers do not live in the same memory chunk.

It affects C and C++ code, and it appears most naturally in data structures built from separately allocated nodes.

How it happens

Pointer subtraction is only well defined for two pointers into the same array or block. Linked list nodes are typically allocated one at a time and can be anywhere. MITRE's example computes list length that way:

struct node {
    int data;
    struct node* next;
};

// Returns the number of nodes in a linked list from
// the given pointer to the head of the list.
int size(struct node* head) {
    struct node* current = head;
    struct node* tail;
    while (current != NULL) {
        tail = current;
        current = current->next;
    }
    return tail - head;
}

The function finds the last node, then subtracts head from tail. MITRE points out there is no guarantee the pointers exist in the same memory area, so the result can be incorrect and allow other unintended behavior.

What an attacker gains

MITRE's list is long: access control, integrity, confidentiality and availability impact, through modifying memory and reading memory, and potentially arbitrary code execution with the privileges of the vulnerable program. A wrong size used in a copy or an allocation is what turns this into memory corruption.

How to find it

MITRE lists:

  • Fuzzing, which runs many varied inputs against the code and can expose crashes, memory corruption or resource consumption, producing repeatable test cases. Rated highly effective.
  • Automated static analysis (SAST), rated highly effective, which models data flow and control flow to find vulnerable patterns.

A quick code search for pointer minus pointer expressions that feed a length or count is also worth doing.

How to fix it

MITRE's recommended solution: save an index variable. Rather than subtract pointers from one another, use an index variable of the same size as the pointers in question, walk from one pointer to the other with it, and calculate the difference. Always validate this number.

For the list example, a counter is all that is needed:

int size(struct node* head) {
    struct node* current = head;
    int count = 0;
    while (current != NULL) {
        count++;
        current = current->next;
    }
    return count;
}

Quick check

When is pointer subtraction safe?

When both pointers point into the same array or memory chunk. Separately allocated list nodes give no such guarantee.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.