Allocate sufficient space when copying a null-terminated byte string from a source to a destination array. Remember to allocate sufficient space to store the string contents as well as the null-termination character.
Non-Compliant Code Example
Command line arguments are read from the command line and stored in process memory. The function main()
, called at program startup, is typically declared as follows when the program accepts command line arguments:
int main(int argc, char *argv[]) { /* ... */ }
Command line arguments are passed to main()
as pointers to null-terminated byte strings in the array members argv[0]
through argv[argc-1]
. If the value of argc
is greater than zero, the string pointed to by argv[0]
represents the program name. If the value of argc
is greater than one, the strings pointed to by argv[1]
through argv[argc-1]
represent the program parameters. In the following definition for main()
the array members argv[0]
through argv[argc-1]
inclusive contain pointers to null-terminated byte strings.
The parameters argc
and argv
and the strings pointed to by the argv
array are not modifiable by the program, and retain their last-stored values between program startup and program termination. This requires that a copy of these parameters be made before the strings can be modified. Vulnerabilities can occur when inadequate space is allocated to copy a command line argument. In this example, the contents of argv[0]
can be manipulated by an attacker to cause a buffer overflow:
int main(int argc, char *argv[]) { ... char prog_name[128]; strcpy(prog_name, argv[0]); ... }
Compliant Solution
The strlen()
function should be used to determine the length of the strings referenced by argv[0]
through argv[argc-1]
so that adequate memory can be dynamically allocated:
int main(int argc, char *argv[]) { ... char * prog_name = (char *)malloc(strlen(argv[0])+1); if (prog_name != NULL) { strcpy(prog_name, argv[1]); } else { /* Couldn't get the memory - recover */ } ... }
Non-Compliant Code Example
The getenv()
function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are implementation-defined. Environment variables can be arbitrarily large, and copying them into fixed length arrays without first determining the size and allocating adequate storage can result in a buffer overflow.
char buff[256]; strcpy(buff, (char *)getenv("EDITOR"));
Compliant Solution
Environmental variables are loaded into process memory when the program is loaded. Resultantly, these null-terminated byte strings have a fixed length. The strlen()
function should be used to determine the length of environmental variables so that adequate memory can be dynamically allocated:
char *editor; char *buff; editor = (char *)getenv("EDITOR"); if (editor) { buff = (char *)malloc(strlen(editor)+1); strcpy(buff, editor); }
Priority: P18 Level: L1
Failure to properly allocate sufficient space when copying null-terminated byte strings can result in buffer overflows and the execution of arbitrary code with the permissions of the vulnerable process by an attacker.
Component |
Value |
---|---|
Severity |
3 (medium) |
Likelihood |
3 (probable) |
Remediation cost |
2 (medium) |
References
- ISO/IEC 9899-1999 Sections 7.1.1 Definitions of terms, Section 7.21 String handling <string.h>, 5.1.2.2.1 Program startup, 7.20.4.5 The getenv function
- Seacord 05 Chapter 2 Strings