CWE Rule 822
Description
Rule Description
The program obtains a value from an untrusted source, converts this value to a pointer, and dereferences the resulting pointer.
Polyspace Implementation
The rule checker checks for these issues:
Tainted NULL or non-null-terminated string
Use of tainted pointer
Examples
Tainted NULL or non-null-terminated string
This issue occurs when strings from unsecure sources are used in string manipulation routines
that implicitly dereference the string buffer, for instance, strcpy
or
sprintf
.
Tainted NULL or non-null-terminated string raises no
defect for a string returned from a call to scanf
-family variadic
functions. Similarly, no defect is raised when you pass the string with a
%s
specifier to printf
-family variadic
functions.
If a string is from an unsecure source, it is possible that an attacker manipulated the string or pointed the string pointer to a different memory location.
If the string is NULL, the string routine cannot dereference the string, causing the program to crash. If the string is not null-terminated, the string routine might not know when the string ends. This error can cause you to write out of bounds, causing a buffer overflow.
Validate the string before you use it. Check that:
The string is not NULL.
The string is null-terminated
The size of the string matches the expected size.
By default, Polyspace® assumes that data from external sources are tainted. See Sources of Tainting in a Polyspace Analysis. To consider any data
that does not originate in the current scope of Polyspace analysis as tainted, use the
command line option -consider-analysis-perimeter-as-trust-boundary
.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define SIZE128 128 #define MAX 40 extern void print_str(const char*); void warningMsg(void) { char userstr[MAX]; read(0,userstr,MAX); char str[SIZE128] = "Warning: "; strncat(str, userstr, SIZE128-(strlen(str)+1));//Noncompliant //Noncompliant print_str(str); }
In this example, the string str
is concatenated
with the argument userstr
. The value of userstr
is
unknown. If the size of userstr
is greater than
the space available, the concatenation overflows.
One possible correction is to check the size of userstr
and
make sure that the string is null-terminated before using it in strncat
.
This example uses a helper function, sansitize_str
,
to validate the string. The defects are concentrated in this function.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define SIZE128 128 #define MAX 40 extern void print_str(const char*); int sanitize_str(char* s) { int res = 0; if (s && (strlen(s) > 0)) { // Noncompliant-TAINTED_STRING only flagged here //Noncompliant // - string is not null // - string has a positive and limited size // - TAINTED_STRING on strlen used as a firewall res = 1; } return res; } void warningMsg(void) { char userstr[MAX]; read(0,userstr,MAX); char str[SIZE128] = "Warning: "; if (sanitize_str(userstr)) strncat(str, userstr, SIZE128-(strlen(str)+1)); print_str(str); }
Another possible correction is to call function errorMsg
and
warningMsg
with specific strings.
#include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE128 128 extern void print_str(const char*); void warningMsg(char* userstr) { char str[SIZE128] = "Warning: "; strncat(str, userstr, SIZE128-(strlen(str)+1)); print_str(str); } void errorMsg(char* userstr) { char str[SIZE128] = "Error: "; strncat(str, userstr, SIZE128-(strlen(str)+1)); print_str(str); } int manageSensorValue(int sensorValue) { int ret = sensorValue; if ( sensorValue < 0 ) { errorMsg("sensor value should be positive"); exit(1); } else if ( sensorValue > 50 ) { warningMsg("sensor value greater than 50 (applying threshold)..."); sensorValue = 50; } return sensorValue; }
Use of tainted pointer
This issue occurs when:
Tainted NULL pointer — the pointer obtained from an unsecure source is not validated against NULL.
Tainted size pointer — the size of the memory zone that an unsecure pointer points to is not validated.
Note
On a single pointer, your code can have instances of Use of tainted pointer, Pointer dereference with tainted offset, and Tainted NULL or non-null-terminated string. Bug Finder raises only the first tainted pointer defect that it finds.
An attacker can give your program a pointer that points to unexpected memory locations. If the pointer is dereferenced to write, the attacker can:
Modify the state variables of a critical program.
Cause your program to crash.
Execute unwanted code.
If the pointer is dereferenced to read, the attacker can:
Read sensitive data.
Cause your program to crash.
Modify a program variable to an unexpected value.
Avoid use of pointers from external sources.
Alternatively, if you trust the external source, sanitize the pointer before dereference. In a separate sanitization function:
Check that the pointer is not NULL.
Check the size of the memory location (if possible). This second check validates whether the size of the data the pointer points to matches the size your program expects.
The defect still appears in the body of the sanitization function. However, if you use a sanitization function, instead of several occurrences, the defect appears only once. You can justify the defect and hide it in later reviews by using code annotations. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
By default, Polyspace assumes that data from external sources are tainted. See Sources of Tainting in a Polyspace Analysis. To consider any data
that does not originate in the current scope of Polyspace analysis as tainted, use the
command line option -consider-analysis-perimeter-as-trust-boundary
.
#include<stdlib.h> void taintedptr(void) { char *p = getenv("ARG"); char x = *(p+10);//Noncompliant //Noncompliant }
In this example, the pointer *p
points to an string of unknown size. During the dereferencing operation, the pointer might
be null or point to unknown memory, which can result in segmentation fault.
One possible correction is to sanitize the pointer before using it. This example checks
whether the pointer is nullptr
before it is dereferenced.
#include<stdlib.h> #include <string.h> void taintedptr(void) { char *p = getenv("ARG"); if(p!=NULL && strlen(p)>10) { char x = *(p+10); } }
Check Information
Category: Pointer Issues |
Version History
Introduced in R2023b
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 (한국어)