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
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);
}
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);
}
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.
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- 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)