ISO/IEC TS 17961 [taintformatio]
Using a tainted value to write to an object using a formatted input or output function
Description
Rule Definition
Using a tainted value to write to an object using a formatted input or output function.1
Polyspace Implementation
This checker checks for these issues:
- Buffer overflow from incorrect string format specifier. 
- Destination buffer overflow in string manipulation. 
- Invalid use of standard library routine. 
- Invalid use of standard library string routine. 
- Tainted NULL or non-null-terminated string. 
- Tainted string format specifier. 
- Invalid use of standard library string routine. 
- Use of dangerous standard function. 
- Insufficient destination buffer size 
Extend Checker
A default Bug Finder analysis might not flag a Tainted NULL or
          non-null-terminated string or Tainted string format
          specifier issue for certain inputs that originate outside of the current
        analysis boundary. 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.
Examples
Buffer overflow from incorrect string
format specifier occurs when the format specifier argument
for functions such as sscanf leads to an overflow
or underflow in the memory buffer argument.
If the format specifier specifies a precision that is greater than the memory buffer size, an overflow occurs. Overflows can cause unexpected behavior such as memory corruption.
Use a format specifier that is compatible with the memory buffer size.
#include <stdio.h>
void func (char *str[]) {
    char buf[32];
    sscanf(str[1], "%33c", buf);
}In this example, buf can contain 32 char elements.
Therefore, the format specifier %33c causes a buffer
overflow.
One possible correction is to use a smaller precision in the format specifier.
#include <stdio.h>
void func (char *str[]) {
    char buf[32];
    sscanf(str[1], "%32c", buf);
}Destination buffer overflow in string manipulation occurs when certain string manipulation functions write to their destination buffer argument at an offset greater than the buffer size.
For instance, when calling the function sprintf(char*
buffer, const char* format), you use a constant string format of
greater size than buffer.
Buffer overflow can cause unexpected behavior such as memory corruption or stopping your system. Buffer overflow also introduces the risk of code injection.
One possible solution is to use alternative functions to constrain the number of characters written. For instance:
- If you use - sprintfto write formatted data to a string, use- snprintf,- _snprintfor- sprintf_sinstead to enforce length control. Alternatively, use- asprintfto automatically allocate the memory required for the destination buffer.
- If you use - vsprintfto write formatted data from a variable argument list to a string, use- vsnprintfor- vsprintf_sinstead to enforce length control.
- If you use - wcscpyto copy a wide string, use- wcsncpy,- wcslcpy, or- wcscpy_sinstead to enforce length control.
Another possible solution is to increase the buffer size.
sprintf Use#include <stdio.h>
void func(void) {
    char buffer[20];
    char *fmt_string = "This is a very long string, it does not fit in the buffer";
    sprintf(buffer, fmt_string);
}In this example, buffer can contain 20 char elements
but fmt_string has a greater size.
snprintf Instead
of sprintfOne possible correction is to use the snprintf function
to enforce length control.
#include <stdio.h>
void func(void) {
    char buffer[20];
    char *fmt_string = "This is a very long string, it does not fit in the buffer";
    snprintf(buffer, 20, fmt_string);
}This issue occurs when you use invalid arguments with a function from the standard library. This defect picks up errors related to other functions not covered by float, integer, memory, or string standard library routines.
Invalid arguments to a standard library function result in undefined behavior.
The fix depends on the root cause of the defect. For instance, the argument to a
            printf function can be NULL because a pointer was
          initialized with NULL and the initialization value was not overwritten
          along a specific execution path.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. 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. 
printf Without a String#include <stdio.h>
#include <stdlib.h>
void print_null(void) {
  printf(NULL); 
}
The function printf takes only string input
          arguments or format specifiers. In this function, the input value is NULL, which is not a
          valid string.
One possible correction is to change the input arguments to fit the requirements of the standard library routine. In this example, the input argument was changed to a character.
#include <stdio.h>
void print_null(void) {
    char zero_val = '0';
    printf((const char*)zero_val); 
}
Invalid use of standard library string routine occurs when a string library function is called with invalid arguments.
The risk depends on the type of invalid arguments. For instance, using the
            strcpy function with a source argument larger than the destination
          argument can result in buffer overflows.
The fix depends on the standard library function involved in the defect. In some
          cases, you can constrain the function arguments before the function call. For instance, if
          the strcpy
          function:
char * strcpy(char * destination, const char* source);strcpy. In
          some cases, you can use an alternative function to avoid the error. For instance, instead
          of strcpy, you can use strncpy to control the number
          of bytes copied. See also Interpret Bug Finder Results in Polyspace Desktop User Interface.See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. 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. 
 #include <string.h>
 #include <stdio.h>
 
 char* Copy_String(void)
 {
  char *res;
  char gbuffer[5],text[20]="ABCDEFGHIJKL";
  res=strcpy(gbuffer,text); 
  /* Error: Size of text is less than gbuffer */
  return(res);
 }
The string text is larger in size than
              gbuffer. Therefore, the function strcpy cannot
            copy text into gbuffer.
One possible correction is to declare the destination string
              gbuffer with equal or larger size than the source string
              text.
#include <string.h>
 #include <stdio.h>
 
 char* Copy_String(void)
 {
  char *res;
  /*Fix: gbuffer has equal or larger size than text */
  char gbuffer[20],text[20]="ABCDEFGHIJKL";
  res=strcpy(gbuffer,text);
  return(res);
 }
This issue occurs when strings from nonsecure sources are used in string manipulation
          routines that implicitly dereference the string buffer, for instance,
            strcpy or sprintf.
The checker 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. 
#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));
	print_str(str);
}
void errorMsg(void)
{
	char userstr[MAX];
	read(0,userstr,MAX);
	char str[SIZE128] = "Error: ";
	strncat(str, userstr, SIZE128-(strlen(str)+1));
	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)) { // Defect only raised here 
		// - 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;
}This issue occurs when printf-style functions use a format
          specifier constructed from nonsecure sources.
If you use externally controlled elements to format a string, you can cause buffer
          overflow or data-representation problems. An attacker can use these string formatting
          elements to view the contents of a stack using %x or write to a stack
          using %n. 
Pass a static string to format string functions. This fix ensures that an external actor cannot control the string.
Another possible fix is to allow only the expected number of arguments. If possible,
          use functions that do not support the vulnerable %n operator in format
          strings.
#include <stdio.h>
#include <unistd.h>
#define MAX 40
void taintedstringformat(void) {
	char userstr[MAX];
	read(0,userstr,MAX);
	printf(userstr);   
}This example prints the input argument userstr. The string is
          unknown. If it contains elements such as %, printf
          can interpret userstr as a string format instead of a string, causing
          your program to crash.
One possible correction is to print userstr explicitly as a string
          so that there is no ambiguity.
#include <stdio.h>
#include <unistd.h>
#define MAX 40
void taintedstringformat(void) {
	char userstr[MAX];
	read(0,userstr,MAX);
	printf("%.20s", userstr);;   
}The Use of dangerous standard function check highlights uses of functions that are inherently dangerous or potentially dangerous given certain circumstances. The following table lists possibly dangerous functions, the risks of using each function, and what function to use instead.
| Dangerous Function | Risk Level | Safer Function | 
|---|---|---|
| gets | Inherently dangerous — You cannot control the length of input from the console. | fgets | 
| cin | Inherently dangerous — You cannot control the length of input from the console. | Avoid or prefaces calls to cinwithcin.width. | 
| strcpy | Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. | strncpy | 
| stpcpy | Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. | stpncpy | 
| lstrcpyorStrCpy | Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. | StringCbCopy,StringCchCopy,strncpy,strcpy_s, orstrlcpy | 
| strcat | Possibly dangerous — If the concatenated result is greater than the destination, buffer overflow can occur. | strncat,strlcat, orstrcat_s | 
| lstrcatorStrCat | Possibly dangerous — If the concatenated result is greater than the destination, buffer overflow can occur. | StringCbCat,StringCchCat,strncay,strcat_s, orstrlcat | 
| wcpcpy | Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. | wcpncpy | 
| wcscat | Possibly dangerous — If the concatenated result is greater than the destination, buffer overflow can occur. | wcsncat,wcslcat, orwcncat_s | 
| wcscpy | Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. | wcsncpy | 
| sprintf | Possibly dangerous — If the output length depends on unknown lengths or values, buffer overflow can occur. | snprintf | 
| vsprintf | Possibly dangerous — If the output length depends on unknown lengths or values, buffer overflow can occur. | vsnprintf | 
These functions can cause buffer overflow, which attackers can use to infiltrate your program.
The fix depends on the root cause of the defect. Often the result details show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show the event history, you can trace back using right-click options in the source code and see previous related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. 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. 
sprintf#include <stdio.h>
#include <string.h>
#include <iostream>
#define BUFF_SIZE 128
int dangerous_func(char *str)
{
    char dst[BUFF_SIZE];
    int r = 0;
    if (sprintf(dst, "%s", str) == 1)
    {
        r += 1;
        dst[BUFF_SIZE-1] = '\0';
    }
    
    return r;
}This example function uses sprintf to copy the string
            str to dst. However, if str is
          larger than the buffer, sprintf can cause buffer overflow.
snprintf with Buffer SizeOne possible correction is to use snprintf instead and specify a
          buffer size.
#include <stdio.h>
#include <string.h>
#include <iostream>
#define BUFF_SIZE 128
int dangerous_func(char *str)
{
    char dst[BUFF_SIZE];
    int r = 0;
    if (snprintf(dst, sizeof(dst), "%s", str) == 1)
    {
        r += 1;
        dst[BUFF_SIZE-1] = '\0';
    }
    
    return r;
}Insufficient destination buffer size occurs when the
          destination buffer in a strcpy operation cannot accommodate the source
          buffer and a null terminator. This issue is reported if the size of the source buffer is
          unknown. Consider this
          code:
int main (int argc, char *argv[])
{
  const char *const input = ((argc && argv[0]) ? argv[0] : "");
  char str[100];
  strcpy(str, input); // Noncompliant
}input is unknown. The size of
          the destination buffer str might be smaller than the value
            (strlen(input)+1). Polyspace® reports a violation on the strcpy
          operation.Using a destination buffer of insufficient size might allow an attacker to cause a buffer overflow. In the preceding code example, if argv[0] contains 100 or more characters, the strcpy operation results in a buffer overflow.
Before calling the function strcpy(), allocate sufficient memory dynamically. For instance, use the function strlen() to determine the size of the source buffer and then allocate the destination buffer so that its size is greater than the value strlen(source) + 1.
Alternatively, use the function strncpy() instead of
            strcpy(). The function strncpy() copies a known
          number of characters from the source buffer to the destination buffer. Because the
          function strncpy() copies a known number of characters, it is a safer
          alternative to strcpy().
In this example, the size of the source buffer is unknown, while the size of the destination buffer is fixed at 128. The size of the destination buffer might not be sufficient to accommodate the characters from the source buffer and terminate the buffer with a null. Polyspace reports a violation of the rule.
#include <string.h>
  
int main(int argc, char *argv[]) {
  const char *const source = (argc && argv[0]) ? argv[0] : "";
  char destination[128];
  strcpy(destination,source);//Noncompliant
  
  return 0;
}strncpy instead of
          strcpyTo fix this issue, use strncpy() to copy a known number of
          characters from the source buffer to the destination
          buffer.
#include <string.h>
#define MAX_ARGS  128  
int main(int argc, char *argv[]) {
  const char *const source = (argc && argv[0]) ? argv[0] : "";
  char destination[MAX_ARGS];
  int num = (strlen(source)+1>MAX_ARGS)?MAX_ARGS:strlen(source)+1;
  strncpy(destination,source,num);//Compliant
  
  return 0;
}This violation is resolved by allocating sufficient memory for the destination buffer. For instance, use the function strlen() to calculate the size of the source buffer and allocate sufficient memory for the destination buffer so that it can accommodate all characters from the source buffer and the null terminator ('\0' ).
#include <string.h>
int main(int argc, char *argv[]) {
	const char *const source = (argc && argv[0]) ? argv[0] : "";
	char* destination = (char *)malloc(strlen(source)+ 1);
	if(destination!=NULL){
		strcpy(destination, source);//Compliant
	}else{
		/*Handle Error*/
	}
	//...
	free(destination);
	return 0;
}Check Information
| Decidability: Undecidable | 
Version History
Introduced in R2019a
1 Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.
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.
Seleziona un sito web
Seleziona un sito web per visualizzare contenuto tradotto dove disponibile e vedere eventi e offerte locali. In base alla tua area geografica, ti consigliamo di selezionare: .
Puoi anche selezionare un sito web dal seguente elenco:
Come ottenere le migliori prestazioni del sito
Per ottenere le migliori prestazioni del sito, seleziona il sito cinese (in cinese o in inglese). I siti MathWorks per gli altri paesi non sono ottimizzati per essere visitati dalla tua area geografica.
Americhe
- América Latina (Español)
- Canada (English)
- United States (English)
Europa
- 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)