C Code Audit
Functions
Code execution
- system
- popen
- exec (
execl
,execlp
,execle
,execv
,execvp
,execvpe
) - posix_spawn (
posix_spawnp
)
gets vs fgets
char gets(char str)
Reads stdin
into str
until a \n
or EOF
(CTRL+D
) occurs. A NULL character is written immediately after the last character read into the array. The \n
character is discarded but not stored in the buffer.
Instead of gets, use fgets that take the length of data to be read.
strcpy vs strncpy
char *strcpy(char * destination, const char * source)
Copies the C string pointed by source
into the array pointed by destination
, including the terminating NULL character.
Instead of strcpy, use the strncpy functions that take the length of data to be copied.
If you run out of space in
destination
before reaching the end of source, you won't get a NULL-terminated string back. This means that you can go from a regular, NULL-terminated string to a non-null-terminated string.
► 0x55555555518e <main+53> call strncpy@plt <strncpy@plt>
dest: 0x7fffffffdb40 ◂— 0
src: 0x555555556008 ◂— 'This is a particularly long string'
n: 0x14
pwndbg> ni
pwndbg> x/s 0x7fffffffdb40
0x7fffffffdb40: "This is a particular\377\177
strcat vs strncat
char *strcat(char * destination, const char * source)
Appends a copy of the source
string to the destination
string. The terminating NULL character in destination
is overwritten by the first character of source
, and a NULL-character is included at the end of the new string formed by the concatenation of both in destination
.
Instead of strcat, use the strncat functions that take the length of data to be copied.
If you run out of space in
destination
before reaching the end of source, you won't get a NULL-terminated string back. This means that you can go from a regular, NULL-terminated string to a non-null-terminated string.
sprintf vs snprintf
Instead of sprintf, use the snprintf functions that take the length of data to be formated.
Good practice
free
To prevent double-free attacks, it is recommended to set the pointer to NULL after it has been freed. Since free(NULL)
is a valid operation that doesn't do anything, you're safe.
free(ptr);
ptr = NULL;
/* code */