CWE Rule 758
Reliance on Undefined, Unspecified, or Implementation-Defined Behavior
Since R2024a
Description
Rule Description
The product uses an API function, data structure, or other entity in a way that relies on properties that are not always guaranteed to hold for that entity.
Polyspace Implementation
The rule checker checks for these issues:
Bitwise operation on negative value
Unsafe conversion between pointer and integer
Use of plain char type for numeric value
Examples
Bitwise operation on negative value
This issue occurs when bitwise operators (>>
, ^
,
|
, ~
, but
,
not
, &
) are used on signed integer
variables with negative values.
If the value of the signed integer is negative, bitwise operation results can be unexpected because:
Bitwise operations on negative values can produce compiler-specific results.
Unexpected calculations can lead to additional vulnerabilities, such as buffer overflow.
When performing bitwise operations, use unsigned
integers
to avoid unexpected results.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
#include <stdio.h> #include <stdarg.h> static void demo_sprintf(const char *format, ...) { int rc; va_list ap; char buf[sizeof("256")]; va_start(ap, format); rc = vsprintf(buf, format, ap); if (rc == -1 || rc >= sizeof(buf)) { /* Handle error */ } va_end(ap); } void bug_bitwiseneg() { int stringify = 0x80000000; demo_sprintf("%u", stringify >> 24); //Noncompliant }
In this example, the statement demo_sprintf("%u", stringify
>> 24)
stops the program unexpectedly. You expect
the result of stringify >> 24
to be 0x80
.
However, the actual result is 0xffffff80
because stringify
is
signed and negative. The sign bit is also shifted.
unsigned
KeywordBy adding the unsigned
keyword, stringify
is
not negative and the right-shift operation gives the expected result
of 0x80
.
#include <stdio.h> #include <stdarg.h> static void demo_sprintf(const char *format, ...) { int rc; va_list ap; char buf[sizeof("256")]; va_start(ap, format); rc = vsprintf(buf, format, ap); if (rc == -1 || rc >= sizeof(buf)) { /* Handle error */ } va_end(ap); } void corrected_bitwiseneg() { unsigned int stringify = 0x80000000; demo_sprintf("%u", stringify >> 24); }
Unsafe conversion between pointer and integer
This issue occurs when you convert between a pointer type, such as
intptr_t
, or
uintprt_t
, and an integer type,
such as enum
,
ptrdiff_t
, or
pid_t
, or vice versa.
The mapping between pointers and integers is not always consistent with the addressing structure of the environment.
Converting from pointers to integers can create:
Truncated or out of range integer values.
Invalid integer types.
Converting from integers to pointers can create:
Misaligned pointers or misaligned objects.
Invalid pointer addresses.
Where possible, avoid pointer-to-integer or integer-to-pointer
conversions. If you want to convert a void
pointer
to an integer, so that you do not change the value, use types:
C99 —
intptr_t
oruintptr_t
C90 —
size_t
orssize_t
unsigned int *badintptrcast(void) { unsigned int *ptr0 = (unsigned int *)0xdeadbeef; //Noncompliant char *ptr1 = (char *)0xdeadbeef; unsigned int *explicit_ptr = reinterpret_cast<unsigned int*>(0xdeadbeef); //Noncompliant return (unsigned int *)(ptr0 - (unsigned int *)ptr1); //Noncompliant }
In this example, there are four conversions, three unsafe conversions and one safe conversion.
The conversion of
0xdeadbeef
to anunsigned int*
causes alignment issues for the pointer. Polyspace® flags this conversion.The conversion of
0xdeadbeef
to achar *
is not flagged because there are no alignment issues forchar
.The explicit
reinterpret_cast
of0xdeadbeef
to anunsigned int*
causes alignment issues for the pointer. Polyspace flags this conversion.The conversion in the return casts
ptrdiff_t
to a pointer. This pointer might point to an invalid address. Polyspace flags this conversion.
intptr_t
One possible correction is to use intptr_t
types
to store the pointer address 0xdeadbeef
. Also,
you can change the second pointer to an integer offset so that there
is no longer a conversion from ptrdiff_t
to
a pointer.
#include <stdint.h> unsigned int *badintptrcast(void) { intptr_t iptr0 = (intptr_t)0xdeadbeef; int offset = 0; return (unsigned int *)(iptr0 - offset); }
Use of plain char type for numeric value
This issue occurs when char
variables without explicit signedness
are used in these ways:
To store non-
char
constants.In an arithmetic operation when the
char
is:A negative value.
The result of a sign changing overflow.
As a buffer offset.
char
variables without a signed
or
unsigned
qualifier can be signed or unsigned depending on your
compiler.
Operations on a plain char can result in unexpected numerical values. If the char is used as an offset, the char can cause buffer overflow or underflow.
When initializing a char variable, to avoid implementation-defined confusion, explicitly state whether the char is signed or unsigned.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
#include <stdio.h> void badplaincharuse(void) { char c = 200; int i = 1000; (void)printf("i/c = %d\n", i/c); //Noncompliant }
In this example, the char variable c
can
be signed or unsigned depending on your compiler. Assuming 8-bit,
two's complement character types, the result is either i/c
= 5
(unsigned char) or i/c = -17
(signed
char). The correct result is unknown
without knowing the signedness of char
.
signed
QualifierOne possible correction is to add a signed
qualifier
to char
. This clarification makes the operation
defined.
#include <stdio.h> void badplaincharuse(void) { signed char c = -56; int i = 1000; (void)printf("i/c = %d\n", i/c); }
Check Information
Category: Others |
Version History
Introduced in R2024a
See Also
External Websites
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)