Main Content

Call to memset family with unintended value

memset or wmemset used with possibly incorrect arguments

Description

This defect occurs when Polyspace® Bug Finder™ detects a use of the memset or wmemset function with possibly incorrect arguments.

void *memset (void *ptr, int value, size_t num) fills the first num bytes of the memory block that ptr points to with the specified value. If the argument value is incorrect, the memory block is initialized with an unintended value.

The unintended initialization can occur in the following cases.

IssueRiskPossible Fix
The second argument is '0' instead of 0 or '\0'.The ASCII value of character '0' is 48 (decimal), 0x30 (hexadecimal), 069 (octal) but not 0 (or '\0').If you want to initialize with '0', use one of the ASCII values. Otherwise, use 0 or '\0'.
The second and third arguments are probably reversed. For instance, the third argument is a literal and the second argument is not a literal.If the order is reversed, a memory block of unintended size is initialized with incorrect arguments.Reverse the order of the arguments.
The second argument cannot be represented in a byte.If the second argument cannot be represented in a byte, and you expect each byte of a memory block to be filled with that argument, the initialization does not occur as intended.

Apply a bit mask to the argument to produce a wrapped or truncated result that can be represented in a byte. When you apply a bit mask, make sure that it produces an expected result.

For instance, replace memset(a, -13, sizeof(a)) with memset(a, (-13) & 0xFF, sizeof(a)).

Fix

The fix depends on the root cause of the defect. See fixes in the table above and code examples with fixes below.

If you do not want to fix the issue, add comments to your result or code to avoid another review. See:

Examples

expand all

#include <string.h>

#define SIZE 32
void func(void) {
    char buf[SIZE];
    int c = -2;
    memset(buf, (char)c, sizeof(buf));
}

In this example, (char)c cannot be represented in a byte.

Correction — Apply Cast

One possible correction is to apply a cast so that the result can be represented in a byte. Check that the result of the cast is an acceptable initialization value. In this correction, Polyspace does not raise this defect. The cast from signed int to unsigned char is contrary to best practices and Polyspace raises the defect Sign change integer conversion overflow.

#include <string.h>

#define SIZE 32
void func(void) {
    char buf[SIZE   ];
    int c = -2;
    memset(buf, (unsigned char)c, sizeof(buf));// Might Overflow 
}
Correction — Avoid Using memset

One possible correction is to reserve the use of memset only for setting or clearing all bits in a buffer. For instance, in this code, memset is called to clear the bits of the character array buf.

#include <string.h>

#define SIZE 32
void func(void) {
    char buf[SIZE   ];
    int c = -2;
    memset(buf, 0, sizeof(buf));//Compliant 
	/* After clearing buf, use it in operations*/
}

Result Information

Group: Programming
Language: C | C++
Default: Off
Command-Line Syntax: MEMSET_INVALID_VALUE
Impact: Low

Version History

Introduced in R2015b