Skip to content

C Code Audit

Functions

Code execution

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 */

References