diff --git "a/cleaned/cwe_top5_sampled.csv" "b/cleaned/cwe_top5_sampled.csv" new file mode 100644--- /dev/null +++ "b/cleaned/cwe_top5_sampled.csv" @@ -0,0 +1,252355 @@ +file,cwe,label,code +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_68b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_68b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +extern char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_68_badData; +extern char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_68b_badSink() +{ + char * data = CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_68_badData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_68b_goodG2BSink() +{ + char * data = CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_68_goodG2BData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +char * CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68_badData; +char * CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cat_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_02.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_02.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_02_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(1) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(1) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_31.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_31_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char * dataCopy = data; + char * data = dataCopy; + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char * dataCopy = data; + char * data = dataCopy; + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51b_badSink(int * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51_bad() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51b_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54e_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54d_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54e_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54d_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_12.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_12_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrueOrFalse()) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrueOrFalse()) + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrueOrFalse()) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_badGlobal; + +char * CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_badSource(char * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_badGlobal) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_goodG2B1Global; +extern int CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_goodG2B1Source(char * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_goodG2B2Source(char * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_22_goodG2B2Global) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_07.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_07.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_07_bad() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + if(staticFive==5) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + if(staticFive==5) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41_badSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41_bad() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41_goodG2BSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_68b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_68b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +extern wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_68_badData; +extern wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_68b_badSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_68_badData; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_68b_goodG2BSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_68_goodG2BData; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_53d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_53c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_53d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_53c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63b_badSink(wchar_t * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63b_goodG2BSink(wchar_t * * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_18.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_18_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + goto source; +source: + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + goto source; +source: + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_05.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_05.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_05_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(staticTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(staticTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_53b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_53b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_53c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_53b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_53c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_53b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_53d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_53d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_53d_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_53d_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_04.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_04.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_04_bad() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(STATIC_CONST_TRUE) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(STATIC_CONST_TRUE) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_17_bad() +{ + int i; + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + for(i = 0; i < 1; i++) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + for(h = 0; h < 1; h++) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_32.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_32.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_32_bad() +{ + int64_t * data; + int64_t * *dataPtr1 = &data; + int64_t * *dataPtr2 = &data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + { + int64_t * data = *dataPtr1; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + *dataPtr1 = data; + } + { + int64_t * data = *dataPtr2; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + int64_t * *dataPtr1 = &data; + int64_t * *dataPtr2 = &data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + { + int64_t * data = *dataPtr1; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + *dataPtr1 = data; + } + { + int64_t * data = *dataPtr2; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_64b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_64b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53b_badSink(twoIntsStruct * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53_bad() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53b_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +static wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_badData; +static wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_badData; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_goodG2BData; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_44.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_44.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_52c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_52b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_52b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcscat(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcscat(data, source); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63b_badSink(char * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_02.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_02.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_02_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(1) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(1) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_31.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_31_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char * dataCopy = data; + char * data = dataCopy; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char * dataCopy = data; + char * data = dataCopy; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61b_badSource(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + data = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61b_badSource(data); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + data = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61b_goodG2BSource(data); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34_unionType myUnion; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34_unionType myUnion; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_17_bad() +{ + int i; + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + for(i = 0; i < 1; i++) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + for(h = 0; h < 1; h++) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_53d_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_53c_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_53c_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_large_13.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_large_13.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: large Large index value that is greater than 10-1 + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_large_13_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_large_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_large_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_large_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_15.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_15_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + switch(6) + { + case 6: + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + break; + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + switch(6) + { + case 6: + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_65b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_65b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_65b_badSink(twoIntsStruct * data) +{ + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_65b_goodG2BSink(twoIntsStruct * data) +{ + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_structType +{ + char * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_structType myStruct); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_structType myStruct; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_structType myStruct; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67b_goodG2BSink(myStruct); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-22a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +int CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_badGlobal = 0; + +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_badSource(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_badGlobal = 1; /* true */ + data = CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_badSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +int CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B1Global = 0; +int CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B2Global = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B1Source(char * data); + +static void goodG2B1() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B1Global = 0; /* false */ + data = CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B1Source(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B2Source(char * data); + +static void goodG2B2() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B2Global = 1; /* true */ + data = CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B2Source(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_54d_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_54c_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_54c_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_18.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_18_bad() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + goto source; +source: + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + goto source; +source: + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_17_bad() +{ + int i; + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + for(i = 0; i < 1; i++) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + for(h = 0; h < 1; h++) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_54e.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_54e.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_54e_badSink(twoIntsStruct * data) +{ + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_54e_goodG2BSink(twoIntsStruct * data) +{ + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68_badData; +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_structType +{ + char * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_structType myStruct); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_structType myStruct; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_structType myStruct; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67b_goodG2BSink(myStruct); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE135_34.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE135_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#define WIDE_STRING L""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"" +#define CHAR_STRING ""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"" + +typedef union +{ + void * unionFirst; + void * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE135_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE135_34_bad() +{ + void * data; + CWE121_Stack_Based_Buffer_Overflow__CWE135_34_unionType myUnion; + data = NULL; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + myUnion.unionFirst = data; + { + void * data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printLine((char *)dest); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + void * data; + CWE121_Stack_Based_Buffer_Overflow__CWE135_34_unionType myUnion; + data = NULL; + /* FIX: Set data to point to a char string */ + data = (void *)CHAR_STRING; + myUnion.unionFirst = data; + { + void * data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * 1); + (void)strcpy(dest, data); + printLine((char *)dest); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + void * data; + CWE121_Stack_Based_Buffer_Overflow__CWE135_34_unionType myUnion; + data = NULL; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + myUnion.unionFirst = data; + { + void * data = myUnion.unionSecond; + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE135_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE135_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE135_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66b_badSink(char * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66_bad() +{ + char * data; + char * dataArray[5]; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_61b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_61b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_61b_badSource(char * data) +{ + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_61b_goodG2BSource(char * data) +{ + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + return data; +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_31.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_31_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_53d_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_53c_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_53c_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_09.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_09.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_09_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_67b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_67b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_67_structType +{ + char * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_67_structType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_18.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_18_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + goto source; +source: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + goto source; +source: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_31.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_31_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + char * dataCopy = data; + char * data = dataCopy; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + { + char * dataCopy = data; + char * data = dataCopy; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_12.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_12_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(globalReturnsTrueOrFalse()) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_13.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_13.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow.label.xml +Template File: point-flaw-13.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* SRC_STR is 32 char long, including the null terminator, for 64-bit architectures */ +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_13_bad() +{ + if(GLOBAL_CONST_FIVE==5) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(GLOBAL_CONST_FIVE!=5) instead of if(GLOBAL_CONST_FIVE==5) */ +static void good1() +{ + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(GLOBAL_CONST_FIVE==5) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_13_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_08.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_08.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_08_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(staticReturnsTrue()) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(staticReturnsTrue()) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_53b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_53b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_53c_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_53b_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_53b_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_54e_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_54d_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_54e_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_54d_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_52c_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_52b_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_52c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_52b_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54c_badSink(int64_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54b_badSink(int64_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54c_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54b_goodG2BSink(int64_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_01.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_01_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_04.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_04.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_04_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(STATIC_CONST_TRUE) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(STATIC_CONST_TRUE) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_cpy_53d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_cpy_53d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_cpy_53d_badSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_cpy_53d_goodG2BSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65b_badSink(int64_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65_bad() +{ + int64_t * data; + /* define a function pointer */ + void (*funcPtr) (int64_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65b_badSink; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65b_goodG2BSink(int64_t * data); + +static void goodG2B() +{ + int64_t * data; + void (*funcPtr) (int64_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65b_goodG2BSink; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_52c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_52b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_52b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_12.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_12_bad() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_54e_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_54d_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_54e_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_54d_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65b_badSink; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65b_goodG2BSink; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_42.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_42.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +static wchar_t * badSource(wchar_t * data) +{ + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + return data; +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_42_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + data = badSource(data); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static wchar_t * goodG2BSource(wchar_t * data) +{ + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + data = goodG2BSource(data); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54e_badSink(int64_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54d_badSink(int64_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54e_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54d_goodG2BSink(int64_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_02.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_02.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_02_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(1) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(1) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_15.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_15_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + switch(6) + { + case 6: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_52c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_52b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_52b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34_bad() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34_unionType myUnion; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34_unionType myUnion; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34_bad() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34_unionType myUnion; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34_unionType myUnion; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_44.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_44.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static void badSink(int data) +{ + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_44_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = badSink; + /* Initialize data */ + data = -1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } +} + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = goodG2BSink; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } +} + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = goodB2GSink; + /* Initialize data */ + data = -1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_44.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_44.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_53d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_53d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_53d_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_53d_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_65b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_65b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_65b_badSink(char * data) +{ + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_65b_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_51b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_51b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_51b_badSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_51b_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_10.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_10_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_64b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_64b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_32.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_32.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_32_bad() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + { + wchar_t * data = *dataPtr1; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + { + wchar_t * data = *dataPtr1; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_54e_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_54d_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_54e_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_54d_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_loop_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_rand_32.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_rand_32.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_rand_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_rand_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_rand_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_rand_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63b_badSink(char * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53b_badSink(int * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53_bad() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53b_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_31.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_31_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65b_badSink; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65b_goodG2BSink; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_31.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_31_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + char * dataCopy = data; + char * data = dataCopy; + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + { + char * dataCopy = data; + char * data = dataCopy; + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_18.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_18_bad() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + goto source; +source: + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + goto source; +source: + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_05.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_05.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_05_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + if(staticTrue) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcscpy(data, source); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + if(staticTrue) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcscpy(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +char * CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68_badData; +char * CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61b_badSource(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + data = CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61b_badSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61b_goodG2BSource(char * data); + +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + data = CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61b_goodG2BSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63b_badSink(char * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_52c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_52c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_52c_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_52c_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65b_badSink; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65b_goodG2BSink; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_53d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_53d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_53d_badSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_53d_goodG2BSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53d_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53c_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53c_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_54b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_54b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_54c_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_54b_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_54b_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34_bad() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34_unionType myUnion; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34_unionType myUnion; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_07.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_07.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_07_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + if(staticFive==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cpy_16.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cpy_16.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cpy_16_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + while(1) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + break; + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strcpy(data, source); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + while(1) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + break; + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strcpy(data, source); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cpy_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cpy_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_declare_cpy_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63b_badSink(wchar_t * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63b_goodG2BSink(wchar_t * * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +static char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_badData; +static char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + char * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_badData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_goodG2BData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_52c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_52c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_52c_badSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_52c_goodG2BSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_54d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_54c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_54c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_badGlobal; + +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_badSource(char * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_badGlobal) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B1Global; +extern int CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B1Source(char * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B2Source(char * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_22_goodG2B2Global) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_08.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_08.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow.label.xml +Template File: point-flaw-08.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* SRC_STR is 32 char long, including the null terminator, for 64-bit architectures */ +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_08_bad() +{ + if(staticReturnsTrue()) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(staticReturnsFalse()) instead of if(staticReturnsTrue()) */ +static void good1() +{ + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(staticReturnsTrue()) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_08_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_10.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_10_bad() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + if(globalTrue) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + if(globalTrue) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_17_bad() +{ + int i; + int * data; + data = NULL; + for(i = 0; i < 1; i++) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + int * data; + data = NULL; + for(h = 0; h < 1; h++) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_06.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_06.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_06_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_53d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_53d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_53d_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_53d_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_10.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_10_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_15.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_15_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + switch(6) + { + case 6: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_loop_06.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_loop_06.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_loop_06_bad() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_loop_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_loop_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_loop_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_16.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_16.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_16_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + while(1) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + break; + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + while(1) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + break; + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34_bad() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34_unionType myUnion; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34_unionType myUnion; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +char * CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68_badData; +char * CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_31.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_31_bad() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + { + int64_t * dataCopy = data; + int64_t * data = dataCopy; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + { + int64_t * dataCopy = data; + int64_t * data = dataCopy; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_06.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_06.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow.label.xml +Template File: point-flaw-06.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * Sinks: type_overrun_memcpy + * GoodSink: Perform the memcpy() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memcpy() + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* SRC_STR is 32 wchar_t long, including the null terminator, for 64-bit architectures */ +#define SRC_STR L""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + wchar_t charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_06_bad() +{ + if(STATIC_CONST_FIVE==5) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printWLine((wchar_t *)structCharVoid.voidSecond); + /* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */ + memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid.charFirst); + printWLine((wchar_t *)structCharVoid.voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(STATIC_CONST_FIVE!=5) instead of if(STATIC_CONST_FIVE==5) */ +static void good1() +{ + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printWLine((wchar_t *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid.charFirst); + printWLine((wchar_t *)structCharVoid.voidSecond); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(STATIC_CONST_FIVE==5) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printWLine((wchar_t *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid.charFirst); + printWLine((wchar_t *)structCharVoid.voidSecond); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_06_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68_badData; +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_52c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_52c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_52c_badSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_52c_goodG2BSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_16.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_16.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_16_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + while(1) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + break; + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + while(1) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + break; + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +static wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_badData; +static wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_badData; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_goodG2BData; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_21.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_21.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static wchar_t * badSource(wchar_t * data) +{ + if(badStatic) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + return data; +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_21_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + badStatic = 1; /* true */ + data = badSource(data); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static wchar_t * goodG2B1Source(wchar_t * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + return data; +} + +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static wchar_t * goodG2B2Source(wchar_t * data) +{ + if(goodG2B2Static) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + return data; +} + +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65b_badSink(int64_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65_bad() +{ + int64_t * data; + /* define a function pointer */ + void (*funcPtr) (int64_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65b_badSink; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65b_goodG2BSink(int64_t * data); + +static void goodG2B() +{ + int64_t * data; + void (*funcPtr) (int64_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65b_goodG2BSink; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_13.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_13.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_13_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(GLOBAL_CONST_FIVE==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65b_badSink; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65b_goodG2BSink; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_10.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_10_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_31.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_31_bad() +{ + int data; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static twoIntsStruct * CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_badData; +static twoIntsStruct * CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + twoIntsStruct * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_badData; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_bad() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + twoIntsStruct * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_goodG2BData; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + } + } +} + +static void goodG2B() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_66b_badSink(int * dataArray[]) +{ + /* copy data out of dataArray */ + int * data = dataArray[2]; + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_66b_goodG2BSink(int * dataArray[]) +{ + int * data = dataArray[2]; + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66b_badSink(char * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66_bad() +{ + char * data; + char * dataArray[5]; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_53b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_53b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_53c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_53b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_53c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_53b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memcpy_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_63b_badSink(int64_t * * dataPtr) +{ + int64_t * data = *dataPtr; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_63b_goodG2BSink(int64_t * * dataPtr) +{ + int64_t * data = *dataPtr; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_04.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_04.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_04_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_18.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_18_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + goto source; +source: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + goto source; +source: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_32.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_32.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_32_bad() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + { + char * data = *dataPtr1; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, ""%s"", source); + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + { + char * data = *dataPtr1; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, ""%s"", source); + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_17_bad() +{ + int i; + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncat_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_01.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_01_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_14.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_14.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_14_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(globalFive==5) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(globalFive==5) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41_badSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41_bad() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41_goodG2BSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_68b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_68b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +extern wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_68_badData; +extern wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_68b_badSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_68_badData; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_68b_goodG2BSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_68_goodG2BData; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53b_badSink(int64_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53_bad() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53b_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +static char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_badData; +static char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + char * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_badData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_goodG2BData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63b_badSink(wchar_t * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63b_goodG2BSink(wchar_t * * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_badGlobal; + +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_badSource(wchar_t * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_badGlobal) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_goodG2B1Global; +extern int CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_goodG2B1Source(wchar_t * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_goodG2B2Source(wchar_t * data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memmove_22_goodG2B2Global) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_64b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_64b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34_unionType myUnion; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strcpy(data, source); + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34_unionType myUnion; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strcpy(data, source); + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_61b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_61b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_61b_badSource(char * data) +{ + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_61b_goodG2BSource(char * data) +{ + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + return data; +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_53d_badSink(twoIntsStruct * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_53c_badSink(twoIntsStruct * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_53d_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_53c_goodG2BSink(twoIntsStruct * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_12.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_12_bad() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + if(globalReturnsTrueOrFalse()) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_51b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_51b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_51b_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_51b_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_54d_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_54c_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_54c_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_large_03.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_large_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: large Large index value that is greater than 10-1 + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_large_03_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(5==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(5==5) + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(5==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(5==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_large_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_large_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_large_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_06.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_06.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_06_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(STATIC_CONST_FIVE==5) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34_unionType myUnion; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34_unionType myUnion; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_14.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_14.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_14_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(globalFive==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(globalFive==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_53d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_53c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_53d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_53c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_06.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_06.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_06_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_53d_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_53c_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_53c_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_54b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_54b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_54c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_54b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_54b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63b_badSink(char * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_06.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_06.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_06_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_32.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_32.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_32_bad() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + { + char * data = *dataPtr1; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + { + char * data = *dataPtr1; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_17_bad() +{ + int i; + char * data; + char dataBuffer[100]; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + char dataBuffer[100]; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64b_badSink(void * dataVoidPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_09.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_09.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow.label.xml +Template File: point-flaw-09.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* SRC_STR is 32 char long, including the null terminator, for 64-bit architectures */ +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_09_bad() +{ + if(GLOBAL_CONST_TRUE) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(GLOBAL_CONST_FALSE) instead of if(GLOBAL_CONST_TRUE) */ +static void good1() +{ + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(GLOBAL_CONST_TRUE) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_09_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_03.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_03_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(5==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(5==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_structType +{ + wchar_t * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_structType myStruct); + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_bad() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_structType myStruct; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_structType myStruct); + +static void goodG2B() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_structType myStruct; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67b_goodG2BSink(myStruct); +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_54e_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_54d_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_54e_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_54d_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_15.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_15_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + switch(6) + { + case 6: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_16.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_16.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_16_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + while(1) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + break; + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + while(1) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + break; + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using wcscpy + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cpy_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_02.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_02.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_02_bad() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(1) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(1) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_18.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_18_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + goto source; +source: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + goto source; +source: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_53d_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_53c_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_53c_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_11.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_11.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_11_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(globalReturnsTrue()) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(globalReturnsTrue()) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_ncpy_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_17.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_17_bad() +{ + int i; + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + for(i = 0; i < 1; i++) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + for(h = 0; h < 1; h++) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_31.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_31_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_04.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_04.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_04_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(STATIC_CONST_TRUE) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(STATIC_CONST_TRUE) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_52c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_52c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_52c_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_52c_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_68b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_68b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern twoIntsStruct * CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_68_badData; +extern twoIntsStruct * CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_68b_badSink() +{ + twoIntsStruct * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_68_badData; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_68b_goodG2BSink() +{ + twoIntsStruct * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_68_goodG2BData; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_52c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_52c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_52c_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memmove_52c_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66b_badSink(char * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66_bad() +{ + char * data; + char * dataArray[5]; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +wchar_t * CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68_badData; +wchar_t * CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_31.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_31_bad() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + { + twoIntsStruct * dataCopy = data; + twoIntsStruct * data = dataCopy; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + { + twoIntsStruct * dataCopy = data; + twoIntsStruct * data = dataCopy; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memcpy_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_15.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_15_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + switch(6) + { + case 6: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + break; + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_51b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_51b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_51b_badSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_51b_goodG2BSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_17.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_17_bad() +{ + int i; + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + for(i = 0; i < 1; i++) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cpy_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_53d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_53c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_53d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_53c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_53d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_53d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_53d_badSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_53d_goodG2BSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_snprintf_51b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_snprintf_51b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_snprintf_51b_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_snprintf_51b_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_18.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_18_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + goto source; +source: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + goto source; +source: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_32.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_32.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_32_bad() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char dataBuffer[100]; + data = dataBuffer; + { + char * data = *dataPtr1; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char dataBuffer[100]; + data = dataBuffer; + { + char * data = *dataPtr1; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65b_badSink(twoIntsStruct * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65_bad() +{ + twoIntsStruct * data; + /* define a function pointer */ + void (*funcPtr) (twoIntsStruct *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65b_badSink; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65b_goodG2BSink(twoIntsStruct * data); + +static void goodG2B() +{ + twoIntsStruct * data; + void (*funcPtr) (twoIntsStruct *) = CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65b_goodG2BSink; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_loop_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_65b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_65b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_65b_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_declare_cat_65b_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_32.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_32.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52c_badSink(twoIntsStruct * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52b_badSink(twoIntsStruct * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52c_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52b_goodG2BSink(twoIntsStruct * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncat_54e.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncat_54e.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncat_54e_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncat_54e_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_54b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_54b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_54c_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_54b_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_54b_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_memcpy_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_structType +{ + int64_t * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_structType myStruct); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_bad() +{ + int64_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_structType myStruct; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_structType myStruct); + +static void goodG2B() +{ + int64_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_structType myStruct; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67b_goodG2BSink(myStruct); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memmove_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_51b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_51b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_51b_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_loop_51b_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +static char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_badData; +static char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + char * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_badData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_goodG2BData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_18.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_18_bad() +{ + int * data; + data = NULL; + goto source; +source: + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + int * data; + data = NULL; + goto source; +source: + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_08.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_08.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_08_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(staticReturnsTrue()) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(staticReturnsTrue()) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_17_bad() +{ + int i; + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + for(i = 0; i < 1; i++) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + for(h = 0; h < 1; h++) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sinks: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +typedef union +{ + int * unionFirst; + int * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34_bad() +{ + int * data; + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34_unionType myUnion; + data = NULL; + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + myUnion.unionFirst = data; + { + int * data = myUnion.unionSecond; + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34_unionType myUnion; + data = NULL; + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + myUnion.unionFirst = data; + { + int * data = myUnion.unionSecond; + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41_badSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41_goodG2BSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_54d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_54c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_54c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66b_badSink(char * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66_bad() +{ + char * data; + char * dataArray[5]; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memmove_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_07.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_07.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_07_bad() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + if(staticFive==5) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + if(staticFive==5) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34_unionType myUnion; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34_unionType myUnion; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_01.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_01_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_loop_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_51b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_51b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_51b_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_snprintf_51b_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_09.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_09.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_09_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_09.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_09.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_09_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_04.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_04.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_04_bad() +{ + int * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63b_badSink(char * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_snprintf_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_12.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_12_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_snprintf_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_54b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_54b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_54c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_54b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_54b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53c_badSink(int * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53b_badSink(int * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53c_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53b_goodG2BSink(int * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_loop_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52c_badSink(twoIntsStruct * data) +{ + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_52c_goodG2BSink(twoIntsStruct * data) +{ + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_66b_badSink(int64_t * dataArray[]) +{ + /* copy data out of dataArray */ + int64_t * data = dataArray[2]; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_66b_goodG2BSink(int64_t * dataArray[]) +{ + int64_t * data = dataArray[2]; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54d_badSink(int64_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54c_badSink(int64_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54d_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54c_goodG2BSink(int64_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_09.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_09.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_09_bad() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53b_badSink(int * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53_bad() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53b_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + int dataBadBuffer[50]; + int dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_11.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_11.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_11_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalReturnsTrue()) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalReturnsTrue()) + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrue()) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrue()) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_52c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_52b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_52b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memmove_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_64b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_64b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using wcscpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34_unionType myUnion; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34_unionType myUnion; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_loop_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_67b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_67b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_67_structType +{ + wchar_t * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_67_structType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_03.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_03_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(5==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(5==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_15.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_15_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + switch(6) + { + case 6: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + break; + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_53b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_53b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_53c_badSink(int * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_53b_badSink(int * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_53c_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_53b_goodG2BSink(int * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_01.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_01_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64b_badSink(void * dataVoidPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_14.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_14.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_14_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive==5) + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalFive==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalFive==5) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_08.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_08.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_08_bad() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(staticReturnsTrue()) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + if(staticReturnsTrue()) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_memcpy_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE135_18.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE135_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#define WIDE_STRING L""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"" +#define CHAR_STRING ""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE135_18_bad() +{ + void * data; + data = NULL; + goto source; +source: + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + goto sink; +sink: + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printLine((char *)dest); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + void * data; + data = NULL; + goto source; +source: + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + goto sink; +sink: + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + void * data; + data = NULL; + goto source; +source: + /* FIX: Set data to point to a char string */ + data = (void *)CHAR_STRING; + goto sink; +sink: + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * 1); + (void)strcpy(dest, data); + printLine((char *)dest); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE135_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE135_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE135_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61b_badSource(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + data = CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61b_badSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +char * CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61b_goodG2BSource(char * data); + +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + data = CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61b_goodG2BSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66b_badSink(wchar_t * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_loop_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63b_badSink(wchar_t * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63b_goodG2BSink(wchar_t * * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_42.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_42.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static int badSource(int data) +{ + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + return data; +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_42_bad() +{ + int data; + /* Initialize data */ + data = -1; + data = badSource(data); + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static int goodG2BSource(int data) +{ + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + return data; +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + data = goodG2BSource(data); + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static int goodB2GSource(int data) +{ + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + return data; +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + data = goodB2GSource(data); + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63b_badSink(wchar_t * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63b_goodG2BSink(wchar_t * * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncpy_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_13.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_13.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_13_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_17_bad() +{ + int i; + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + for(i = 0; i < 1; i++) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34_unionType myUnion; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34_unionType myUnion; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_memcpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_54d_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_54c_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_54c_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memcpy_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_67b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_67b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_67_structType +{ + wchar_t * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_67_structType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64b_badSink(void * dataVoidPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64_bad() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int64_t * data; + int64_t * dataBadBuffer = (int64_t *)ALLOCA(50*sizeof(int64_t)); + int64_t * dataGoodBuffer = (int64_t *)ALLOCA(100*sizeof(int64_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65b_badSink; + char dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65b_goodG2BSink; + char dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static int64_t * CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_badData; +static int64_t * CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + int64_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_badData; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_bad() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int64_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_goodG2BData; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +static void goodG2B() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_11.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_11.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_11_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(globalReturnsTrue()) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(globalReturnsTrue()) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63b_badSink(char * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_51b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_51b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_51b_badSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strcat(data, source); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_51b_goodG2BSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strcat(data, source); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_54d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_54c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_54c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_02.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_02.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_02_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(1) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(1) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66b_badSink(wchar_t * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE135_15.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE135_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#include + +#define WIDE_STRING L""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"" +#define CHAR_STRING ""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE135_15_bad() +{ + void * data; + data = NULL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printLine((char *)dest); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + void * data; + data = NULL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + void * data; + data = NULL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + void * data; + data = NULL; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Set data to point to a char string */ + data = (void *)CHAR_STRING; + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * 1); + (void)strcpy(dest, data); + printLine((char *)dest); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + void * data; + data = NULL; + switch(6) + { + case 6: + /* FIX: Set data to point to a char string */ + data = (void *)CHAR_STRING; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * 1); + (void)strcpy(dest, data); + printLine((char *)dest); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE135_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE135_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE135_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_09.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_09.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_09_bad() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + if(GLOBAL_CONST_TRUE) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_53d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_53c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_53d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_53c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cat_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_01.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_01_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strcat(data, source); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strcat(data, source); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_structType +{ + char * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_structType myStruct); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_structType myStruct; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_structType myStruct; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67b_goodG2BSink(myStruct); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_13.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_13.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_13_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_10.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_10_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(globalTrue) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, ""%s"", source); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, ""%s"", source); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(globalTrue) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, ""%s"", source); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_snprintf_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_54e_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_54d_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_54e_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_54d_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncat_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_12.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow.label.xml +Template File: point-flaw-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * Sinks: type_overrun_memcpy + * GoodSink: Perform the memcpy() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memcpy() + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* SRC_STR is 32 char long, including the null terminator, for 64-bit architectures */ +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_12_bad() +{ + if(globalReturnsTrueOrFalse()) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */ + memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } + else + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses the GoodSink on both sides of the ""if"" statement */ +static void good1() +{ + if(globalReturnsTrueOrFalse()) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } + else + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_12_good() +{ + good1(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using wcscpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34_bad() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34_unionType myUnion; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34_unionType myUnion; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53b_badSink(int * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53_bad() +{ + int * data; + data = NULL; + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53b_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + data = NULL; + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +int * CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68_badData; +int * CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68_bad() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_03.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_03_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + if(5==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + if(5==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_08.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_08.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_08_bad() +{ + int * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66b_badSink(wchar_t * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_badGlobal; + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_badSink(int data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_badGlobal) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodB2G1Global; +extern int CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodB2G2Global; +extern int CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodB2G1Sink(int data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodB2G2Sink(int data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodB2G2Global) + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodG2BSink(int data) +{ + if(CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_22_goodG2BGlobal) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_54b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_54b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_54c_badSink(int64_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_54b_badSink(int64_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_54c_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_54b_goodG2BSink(int64_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memmove_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_42.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_42.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static char * badSource(char * data) +{ + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + return data; +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_42_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + data = badSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static char * goodG2BSource(char * data) +{ + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + data = goodG2BSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_42.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_42.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static char * badSource(char * data) +{ + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + return data; +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_42_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + data = badSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static char * goodG2BSource(char * data) +{ + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + data = goodG2BSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncat_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow.label.xml +Template File: point-flaw-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* SRC_STR is 32 char long, including the null terminator, for 64-bit architectures */ +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_17_bad() +{ + int j; + for(j = 0; j < 1; j++) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses the GoodSinkBody in the for statements */ +static void good1() +{ + int k; + for(k = 0; k < 1; k++) + { + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_17_good() +{ + good1(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memmove_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +char * CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68_badData; +char * CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_ncpy_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_63b_badSink(int * * dataPtr) +{ + int * data = *dataPtr; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_63b_goodG2BSink(int * * dataPtr) +{ + int * data = *dataPtr; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_15.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_15_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + switch(6) + { + case 6: + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcscpy(data, source); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + switch(6) + { + case 6: + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcscpy(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_51b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_51b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_51b_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_51b_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_01.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_01_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_68b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_68b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern int * CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_68_badData; +extern int * CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_68b_badSink() +{ + int * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_68_badData; + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_68b_goodG2BSink() +{ + int * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_loop_68_goodG2BData; + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_53b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_53b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_53c_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_53b_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_53b_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_64b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_64b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_12.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_12_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef union +{ + int unionFirst; + int unionSecond; +} CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34_unionType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34_bad() +{ + int data; + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34_unionType myUnion; + /* Initialize data */ + data = -1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34_unionType myUnion; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34_unionType myUnion; + /* Initialize data */ + data = -1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_12.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_12_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54d_badSink(int data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54c_badSink(int data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54d_goodG2BSink(int data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54c_goodG2BSink(int data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54d_goodB2GSink(int data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54c_goodB2GSink(int data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE129_listen_socket_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_10.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_10_bad() +{ + int * data; + data = NULL; + if(globalTrue) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(globalTrue) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_03.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_03_bad() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + if(5==5) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + int * dataBadBuffer = (int *)ALLOCA(50*sizeof(int)); + int * dataGoodBuffer = (int *)ALLOCA(100*sizeof(int)); + if(5==5) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memcpy_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_04.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_04.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_04_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(STATIC_CONST_TRUE) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + if(STATIC_CONST_TRUE) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_13.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_13.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_13_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memcpy_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_54e.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_54e.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_54e_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_54e_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_68b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_68b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +extern wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_68_badData; +extern wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_68b_badSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_68_badData; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_68b_goodG2BSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_snprintf_68_goodG2BData; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54e.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54e.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54e_badSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_alloca_loop_54e_goodG2BSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + } + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_17.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_17.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_17_bad() +{ + int i; + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + for(i = 0; i < 1; i++) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + for(h = 0; h < 1; h++) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memcpy_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_44.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_44.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memcpy_11.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memcpy_11.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memcpy_11_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(globalReturnsTrue()) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + if(globalReturnsTrue()) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memcpy_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memcpy_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memcpy_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_02.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_02.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_02_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(1) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(1) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_loop_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_52c_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_52b_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_52c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_52b_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_03.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_03_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(5==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + if(5==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_loop_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncat_53d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncat_53d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncat_53d_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_ncat_53d_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_64b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_64b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + twoIntsStruct * * dataPtr = (twoIntsStruct * *)dataVoidPtr; + /* dereference dataPtr into data */ + twoIntsStruct * data = (*dataPtr); + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memcpy_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + twoIntsStruct * * dataPtr = (twoIntsStruct * *)dataVoidPtr; + /* dereference dataPtr into data */ + twoIntsStruct * data = (*dataPtr); + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_03.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_03_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(5==5) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(5==5) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + strncat(data, source, 100); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncat_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_44.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_44.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_loop_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_structType +{ + wchar_t * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_structType myStruct); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_bad() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_structType myStruct; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_structType myStruct); + +static void goodG2B() +{ + wchar_t * data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_structType myStruct; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67b_goodG2BSink(myStruct); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_snprintf_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_16.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_16.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_16_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + while(1) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + break; + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + while(1) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + break; + } + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_cpy_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68_badData; +char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncpy_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_54e_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_54d_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_54e_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_54d_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_02.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_02.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_02_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(1) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(1) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_10.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_10_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(globalTrue) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strcpy(data, source); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strcpy(data, source); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + if(globalTrue) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + strcpy(data, source); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_01.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_01_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memmove_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_03.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_03_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + if(5==5) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcscat(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcscat(data, source); + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + if(5==5) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcscat(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_declare_cat_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_32.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_32.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_32_bad() +{ + twoIntsStruct * data; + twoIntsStruct * *dataPtr1 = &data; + twoIntsStruct * *dataPtr2 = &data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + { + twoIntsStruct * data = *dataPtr1; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + *dataPtr1 = data; + } + { + twoIntsStruct * data = *dataPtr2; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + twoIntsStruct * data; + twoIntsStruct * *dataPtr1 = &data; + twoIntsStruct * *dataPtr2 = &data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + { + twoIntsStruct * data = *dataPtr1; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + *dataPtr1 = data; + } + { + twoIntsStruct * data = *dataPtr2; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_63b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_63b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_63b_badSink(twoIntsStruct * * dataPtr) +{ + twoIntsStruct * data = *dataPtr; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_loop_63b_goodG2BSink(twoIntsStruct * * dataPtr) +{ + twoIntsStruct * data = *dataPtr; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + } + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53b_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_09.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_09.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_09_bad() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + twoIntsStruct * dataBadBuffer = (twoIntsStruct *)ALLOCA(50*sizeof(twoIntsStruct)); + twoIntsStruct * dataGoodBuffer = (twoIntsStruct *)ALLOCA(100*sizeof(twoIntsStruct)); + if(GLOBAL_CONST_TRUE) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_alloca_memmove_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_54b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_54b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_54c_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_54b_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_54b_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__src_wchar_t_alloca_cat_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66b_badSink(wchar_t * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t dataBadBuffer[10]; + wchar_t dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_loop_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_67b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_67b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_67_structType +{ + int * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_67_structType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_67_structType myStruct) +{ + int * data = myStruct.structFirst; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_67_structType myStruct) +{ + int * data = myStruct.structFirst; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_12.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_12_bad() +{ + int * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + int * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_loop_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_memmove_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66b_badSink(char * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66_bad() +{ + char * data; + char * dataArray[5]; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_54d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_54c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_54c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_ncpy_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_53d_badSink(int * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_53c_badSink(int * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_53d_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_53c_goodG2BSink(int * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_alloca_memmove_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_67b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_67b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_67_structType +{ + int * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_67_structType; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_67_structType myStruct) +{ + int * data = myStruct.structFirst; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_67_structType myStruct) +{ + int * data = myStruct.structFirst; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_15.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow.label.xml +Template File: point-flaw-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* SRC_STR is 32 wchar_t long, including the null terminator, for 64-bit architectures */ +#define SRC_STR L""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + wchar_t charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_15_bad() +{ + switch(6) + { + case 6: + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printWLine((wchar_t *)structCharVoid.voidSecond); + /* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid.charFirst); + printWLine((wchar_t *)structCharVoid.voidSecond); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() changes the switch to switch(5) */ +static void good1() +{ + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printWLine((wchar_t *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid.charFirst); + printWLine((wchar_t *)structCharVoid.voidSecond); + } + break; + } +} + +/* good2() reverses the blocks in the switch */ +static void good2() +{ + switch(6) + { + case 6: + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printWLine((wchar_t *)structCharVoid.voidSecond); + /* FIX: Use sizeof(structCharVoid.charFirst) to avoid overwriting the pointer voidSecond */ + memmove(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid.charFirst)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid.charFirst); + printWLine((wchar_t *)structCharVoid.voidSecond); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_15_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64b_badSink(void * dataVoidPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_ncpy_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_54d.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_54d.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_54e_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_54d_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_54e_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_54d_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_declare_ncpy_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_52c_badSink(int * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_52b_badSink(int * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_52c_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_52b_goodG2BSink(int * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_int_declare_memmove_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +static wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_badData; +static wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_badData; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_goodG2BData; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100]; + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_memcpy_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_01.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_01_bad() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + int64_t dataBadBuffer[50]; + int64_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_int64_t_declare_memcpy_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64b_badSink(void * dataVoidPtr); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_10.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_10_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalTrue) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalTrue) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalTrue) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalTrue) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalTrue) + { + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalTrue) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalTrue) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalTrue) + { + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_fscanf_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE135_16.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE135_16.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#define WIDE_STRING L""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"" +#define CHAR_STRING ""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE135_16_bad() +{ + void * data; + data = NULL; + while(1) + { + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printLine((char *)dest); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + void * data; + data = NULL; + while(1) + { + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)WIDE_STRING; + break; + } + while(1) + { + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)ALLOCA((dataLen+1) * sizeof(wchar_t)); + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + void * data; + data = NULL; + while(1) + { + /* FIX: Set data to point to a char string */ + data = (void *)CHAR_STRING; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)ALLOCA((dataLen+1) * 1); + (void)strcpy(dest, data); + printLine((char *)dest); + } + break; + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE135_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE135_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE135_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_alloca_cpy_53b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_alloca_cpy_53b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_alloca_cpy_53c_badSink(wchar_t * data); + +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_alloca_cpy_53b_badSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_alloca_cpy_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_alloca_cpy_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_alloca_cpy_53b_goodG2BSink(wchar_t * data) +{ + CWE121_Stack_Based_Buffer_Overflow__dest_wchar_t_alloca_cpy_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_12.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_12_bad() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + twoIntsStruct * data; + twoIntsStruct dataBadBuffer[50]; + twoIntsStruct dataGoodBuffer[100]; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_01.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_01.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_01_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_cpy_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_18.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_18_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + goto source; +source: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + goto source; +source: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_66b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_66b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_66b_badSink(int dataArray[]) +{ + /* copy data out of dataArray */ + int data = dataArray[2]; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_66b_goodG2BSink(int dataArray[]) +{ + int data = dataArray[2]; + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE129_connect_socket_66b_goodB2GSink(int dataArray[]) +{ + int data = dataArray[2]; + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_18.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_18.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_18_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + goto source; +source: + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + goto source; +source: + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63b_badSink(char * * dataPtr); + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63b_goodG2BSink(&data); +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_53c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_53c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_53d_badSink(twoIntsStruct * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_53c_badSink(twoIntsStruct * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_53d_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_53c_goodG2BSink(twoIntsStruct * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE805_struct_declare_memmove_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41_badSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t)); + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_ncpy_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_65b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_65b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_65b_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_declare_ncpy_65b_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41_bad() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the sizeof(data)-strlen(data) is less than the length of source */ + wcsncat(data, source, 100); + printWLine(data); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t)); + wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_ncat_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_10.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_10_bad() +{ + int * data; + data = NULL; + if(globalTrue) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(globalTrue) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)ALLOCA(10*sizeof(int)); + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE131_memmove_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_68b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_68b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +extern wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_68_badData; +extern wchar_t * CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_68b_badSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_68_badData; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_68b_goodG2BSink() +{ + wchar_t * data = CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_68_goodG2BData; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_08.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_08.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_08_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memmove_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_memmove_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_08.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_08.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_08_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(staticReturnsTrue()) + { + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + if(staticReturnsTrue()) + { + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_07.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_07.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_07_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(staticFive==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_declare_cpy_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66b_badSink(wchar_t * dataArray[]); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + dataArray[2] = data; + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66b_goodG2BSink(dataArray); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_loop_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_12.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_12_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(globalReturnsTrueOrFalse()) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__src.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68_badData; +char * CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68b_badSink(); + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68_badData = data; + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68_goodG2BData = data; + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68b_goodG2BSink(); +} + +void CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__src_char_alloca_cat_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_03.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_03.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_03_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(5==5) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA((10)*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA((10+1)*sizeof(char)); + if(5==5) + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_10.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_10.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_10_bad() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100]; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_declare_memcpy_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_31.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_31.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_31_bad() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBadBuffer[50]; + wchar_t dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_declare_memmove_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_54c.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_54c.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_54d_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_54c_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_54c_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cat_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE129_large_15.c,CWE121,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE129_large_15.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE129.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: large Large index value that is greater than 10-1 + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_large_15_bad() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int buffer[10] = { 0 }; + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + break; + } + switch(7) + { + case 7: + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int buffer[10] = { 0 }; + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE129_large_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_large_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE129_large_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61b_badSource(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + data = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61b_badSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +char * CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61b_goodG2BSource(char * data); + +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + data = CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61b_goodG2BSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_snprintf_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_65b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_65b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sinks: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_65b_badSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_memcpy_65b_goodG2BSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + } +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_06.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_06.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_06_bad() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t * dataBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t)); + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_wchar_t_alloca_ncat_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__dest.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sinks: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_structType +{ + char * structFirst; +} CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67b_badSink(CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_structType myStruct); + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_bad() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_structType myStruct; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67b_goodG2BSink(CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_structType myStruct; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67b_goodG2BSink(myStruct); +} + +void CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__dest_char_alloca_cpy_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_12.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_12.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE806.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_12_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE806_char_alloca_ncat_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_52b.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_52b.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Point data to a buffer that does not have space for a NULL terminator + * GoodSource: Point data to a buffer that includes space for a NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_52c_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_52b_badSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_52b_goodG2BSink(char * data) +{ + CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_ncpy_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51a.c,CWE121,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51a.c +Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE805.string.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 121 Stack Based Buffer Overflow + * BadSource: Set data pointer to the bad buffer + * GoodSource: Set data pointer to the good buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51b_badSink(char * data); + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a ""small"" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a ""large"" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FIX: Set a pointer to a ""large"" buffer, thus avoiding buffer overflows in the sinks. */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51b_goodG2BSink(data); +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memmove_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_spawnv_21.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnv_21.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static char * badSource(char * data) +{ + if(badStatic) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + return data; +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_21_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + badStatic = 1; /* true */ + data = badSource(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static char * goodG2B1Source(char * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static char * goodG2B2Source(char * data) +{ + if(goodG2B2Static) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnv_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnv_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_system_52b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_system_52b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_system_52c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_system_52b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_file_system_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_file_system_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_system_52b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_file_system_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_11.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_11.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_11_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_execl_01.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execl_01.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execl_01_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execl_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_execvp_22a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execvp_22a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-22a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +int CWE78_OS_Command_Injection__char_environment_w32_execvp_22_badGlobal = 0; + +char * CWE78_OS_Command_Injection__char_environment_w32_execvp_22_badSource(char * data); + +void CWE78_OS_Command_Injection__char_environment_w32_execvp_22_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_environment_w32_execvp_22_badGlobal = 1; /* true */ + data = CWE78_OS_Command_Injection__char_environment_w32_execvp_22_badSource(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +int CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B1Global = 0; +int CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B2Global = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B1Source(char * data); + +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B1Global = 0; /* false */ + data = CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B1Source(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B2Source(char * data); + +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B2Global = 1; /* true */ + data = CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B2Source(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_execvp_22_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_execvp_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_execvp_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_system_52c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_system_52c.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_52c_badSink(wchar_t * data) +{ + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_52c_goodG2BSink(wchar_t * data) +{ + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_system_03.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_system_03.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_system_03_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(5==5) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(5==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__char_console_system_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_system_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_system_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_popen_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_popen_53a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_popen_53b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_popen_53_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + CWE78_OS_Command_Injection__char_console_popen_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_popen_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_console_popen_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_console_popen_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_popen_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_popen_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_execlp_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execlp_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +extern char * CWE78_OS_Command_Injection__char_environment_execlp_68_badData; +extern char * CWE78_OS_Command_Injection__char_environment_execlp_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_execlp_68b_badSink() +{ + char * data = CWE78_OS_Command_Injection__char_environment_execlp_68_badData; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_execlp_68b_goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_environment_execlp_68_goodG2BData; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_12.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_12.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_12_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_52c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_52c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_52c_badSink(wchar_t * data) +{ + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_52c_goodG2BSink(wchar_t * data) +{ + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_54c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _execvp + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_54d_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_54c_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_54c_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_system_51b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_system_51b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_system_51b_badSink(char * data) +{ + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_system_51b_goodG2BSink(char * data) +{ + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_13.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_13.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_13_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE==5) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32spawnl_51a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32spawnl_51a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_w32spawnl_51b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_environment_w32spawnl_51_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__char_environment_w32spawnl_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__char_environment_w32spawnl_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_environment_w32spawnl_51b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_environment_w32spawnl_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32spawnl_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32spawnl_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_execlp_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_execlp_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with execlp + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_execlp_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECVP _wexecvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +wchar_t * CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68_badData; +wchar_t * CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68b_badSink(); + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68_badData = data; + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68_goodG2BData = data; + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68b_goodG2BSink(); +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +extern char * CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_68_badData; +extern char * CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_68b_badSink() +{ + char * data = CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_68_badData; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_68b_goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_68_goodG2BData; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_18.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_18.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_18_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_12.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_12.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_12_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_execlp_31.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execlp_31.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with execlp + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_execlp_31_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + { + char * dataCopy = data; + char * data = dataCopy; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char * dataCopy = data; + char * data = dataCopy; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__char_environment_execlp_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_execlp_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_execlp_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61b_badSource(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61b_badSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61b_goodG2BSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_execlp_34.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_execlp_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with execlp + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE78_OS_Command_Injection__char_connect_socket_execlp_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_34_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_connect_socket_execlp_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_connect_socket_execlp_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_execlp_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_execlp_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_execl_15.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execl_15.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execl_15_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execl_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_system_17.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_system_17.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_system_17_bad() +{ + int i; + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + for(i = 0; i < 1; i++) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_system_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_system_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_system_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_execvp_65b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_execvp_65b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32_execvp_65b_badSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32_execvp_65b_goodG2BSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_popen_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_popen_68b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +extern char * CWE78_OS_Command_Injection__char_connect_socket_popen_68_badData; +extern char * CWE78_OS_Command_Injection__char_connect_socket_popen_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_popen_68b_badSink() +{ + char * data = CWE78_OS_Command_Injection__char_connect_socket_popen_68_badData; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_popen_68b_goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_connect_socket_popen_68_goodG2BData; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68_badData; +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68b_badSink(); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68_badData = data; + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68_goodG2BData = data; + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68b_goodG2BSink(); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_execv_65b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_execv_65b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_65b_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_65b_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_44.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_44.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_execlp_67a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_execlp_67a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +typedef struct _CWE78_OS_Command_Injection__wchar_t_file_execlp_67_structType +{ + wchar_t * structFirst; +} CWE78_OS_Command_Injection__wchar_t_file_execlp_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_execlp_67b_badSink(CWE78_OS_Command_Injection__wchar_t_file_execlp_67_structType myStruct); + +void CWE78_OS_Command_Injection__wchar_t_file_execlp_67_bad() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_file_execlp_67_structType myStruct; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + myStruct.structFirst = data; + CWE78_OS_Command_Injection__wchar_t_file_execlp_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_execlp_67b_goodG2BSink(CWE78_OS_Command_Injection__wchar_t_file_execlp_67_structType myStruct); + +static void goodG2B() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_file_execlp_67_structType myStruct; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + myStruct.structFirst = data; + CWE78_OS_Command_Injection__wchar_t_file_execlp_67b_goodG2BSink(myStruct); +} + +void CWE78_OS_Command_Injection__wchar_t_file_execlp_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_execlp_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_execlp_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_spawnv_42.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnv_42.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +static char * badSource(char * data) +{ + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + return data; +} + +void CWE78_OS_Command_Injection__char_console_w32_spawnv_42_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = badSource(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static char * goodG2BSource(char * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = goodG2BSource(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_console_w32_spawnv_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnv_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnv_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65b_badSink; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65b_goodG2BSink; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _wexecvp + +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_68_badData; +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_68b_badSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_68_badData; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_68b_goodG2BSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_68_goodG2BData; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_w32spawnl_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32spawnl_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32spawnl_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32spawnl_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_31.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_31.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECVP _wexecvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_31_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_popen_22a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_popen_22a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-22a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +int CWE78_OS_Command_Injection__char_console_popen_22_badGlobal = 0; + +char * CWE78_OS_Command_Injection__char_console_popen_22_badSource(char * data); + +void CWE78_OS_Command_Injection__char_console_popen_22_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + CWE78_OS_Command_Injection__char_console_popen_22_badGlobal = 1; /* true */ + data = CWE78_OS_Command_Injection__char_console_popen_22_badSource(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +int CWE78_OS_Command_Injection__char_console_popen_22_goodG2B1Global = 0; +int CWE78_OS_Command_Injection__char_console_popen_22_goodG2B2Global = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_console_popen_22_goodG2B1Source(char * data); + +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + CWE78_OS_Command_Injection__char_console_popen_22_goodG2B1Global = 0; /* false */ + data = CWE78_OS_Command_Injection__char_console_popen_22_goodG2B1Source(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_console_popen_22_goodG2B2Source(char * data); + +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + CWE78_OS_Command_Injection__char_console_popen_22_goodG2B2Global = 1; /* true */ + data = CWE78_OS_Command_Injection__char_console_popen_22_goodG2B2Source(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__char_console_popen_22_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_popen_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_popen_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_system_01.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_system_01.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_system_01_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_system_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_system_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_system_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execv_07.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execv_07.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _execv + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_07_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execv_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execv_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32spawnl_52b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32spawnl_52b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_w32spawnl_52c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_w32spawnl_52b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_w32spawnl_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_w32spawnl_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32spawnl_52b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_w32spawnl_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_w32_execv_34.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_execv_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with execv + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _execv + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE78_OS_Command_Injection__char_console_w32_execv_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32_execv_34_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_console_w32_execv_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_console_w32_execv_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } + } +} + +void CWE78_OS_Command_Injection__char_console_w32_execv_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_execv_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_execv_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_execlp_41.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_execlp_41.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_41_badSink(char * data) +{ + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_41_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_execlp_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_41_goodG2BSink(char * data) +{ + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_execlp_41_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_execlp_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_execlp_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_popen_01.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_popen_01.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_popen_01_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_popen_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_popen_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_popen_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_execl_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_execl_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_execl_08_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_execl_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_execl_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_execl_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_execlp_64a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_execlp_64a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_execlp_64b_badSink(void * dataVoidPtr); + +void CWE78_OS_Command_Injection__wchar_t_console_execlp_64_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + CWE78_OS_Command_Injection__wchar_t_console_execlp_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_execlp_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_console_execlp_64b_goodG2BSink(&data); +} + +void CWE78_OS_Command_Injection__wchar_t_console_execlp_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_execlp_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_execlp_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_popen_18.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_popen_18.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_popen_18_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_popen_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_popen_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_popen_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_65b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_65b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_65b_badSink(char * data) +{ + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_65b_goodG2BSink(char * data) +{ + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_execlp_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execlp_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with execlp + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execlp_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_execlp_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: system + * BadSink : Execute command in data using system() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61b_badSource(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + data = CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61b_badSource(data); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + data = CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61b_goodG2BSource(data); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_system_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_popen_54d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_popen_54d.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_popen_54e_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_popen_54d_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_popen_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_popen_54e_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_popen_54d_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_popen_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_10.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_10.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_10_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_badGlobal; + +wchar_t * CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_badSource(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_badGlobal) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_goodG2B1Global; +extern int CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_goodG2B1Source(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_goodG2B2Source(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_22_goodG2B2Global) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32_spawnlp_01.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnlp_01.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_spawnlp_01_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnlp_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnlp_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnlp_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_spawnv_61a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnv_61a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +char * CWE78_OS_Command_Injection__char_console_w32_spawnv_61b_badSource(char * data); + +void CWE78_OS_Command_Injection__char_console_w32_spawnv_61_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__char_console_w32_spawnv_61b_badSource(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +char * CWE78_OS_Command_Injection__char_console_w32_spawnv_61b_goodG2BSource(char * data); + +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__char_console_w32_spawnv_61b_goodG2BSource(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_console_w32_spawnv_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnv_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnv_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _wexecv + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_popen_22b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_popen_22b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE78_OS_Command_Injection__char_connect_socket_popen_22_badGlobal; + +char * CWE78_OS_Command_Injection__char_connect_socket_popen_22_badSource(char * data) +{ + if(CWE78_OS_Command_Injection__char_connect_socket_popen_22_badGlobal) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE78_OS_Command_Injection__char_connect_socket_popen_22_goodG2B1Global; +extern int CWE78_OS_Command_Injection__char_connect_socket_popen_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_connect_socket_popen_22_goodG2B1Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_connect_socket_popen_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_connect_socket_popen_22_goodG2B2Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_connect_socket_popen_22_goodG2B2Global) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_54c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_54d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_54c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_54c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_execl_34.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_execl_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: execl + * BadSink : execute command with execl + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE78_OS_Command_Injection__char_connect_socket_execl_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_execl_34_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_connect_socket_execl_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_connect_socket_execl_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_execl_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_execl_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_execl_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_system_22b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_system_22b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE78_OS_Command_Injection__char_console_system_22_badGlobal; + +char * CWE78_OS_Command_Injection__char_console_system_22_badSource(char * data) +{ + if(CWE78_OS_Command_Injection__char_console_system_22_badGlobal) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE78_OS_Command_Injection__char_console_system_22_goodG2B1Global; +extern int CWE78_OS_Command_Injection__char_console_system_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_console_system_22_goodG2B1Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_console_system_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_console_system_22_goodG2B2Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_console_system_22_goodG2B2Global) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_execl_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execl_65a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: execl + * BadSink : execute command with execl + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_execl_65b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_environment_execl_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_environment_execl_65b_badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_execl_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_environment_execl_65b_goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_environment_execl_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_execl_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_execl_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_09.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_09.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_09_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63b_badSink(char * * dataPtr); + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63b_goodG2BSink(&data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_system_10.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_system_10.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_system_10_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_system_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_system_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_system_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_63b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_popen_61a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_popen_61a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_file_popen_61b_badSource(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_popen_61_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + data = CWE78_OS_Command_Injection__wchar_t_file_popen_61b_badSource(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_file_popen_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + data = CWE78_OS_Command_Injection__wchar_t_file_popen_61b_goodG2BSource(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_popen_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_popen_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_popen_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_08_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_53c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_53c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_53d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_53c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_53c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_popen_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_popen_66b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_popen_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_popen_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_execlp_11.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_execlp_11.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_execlp_11_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_console_execlp_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_execlp_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_execlp_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_16.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_16.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_16_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_31.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_31.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_31_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_execlp_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_execlp_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_execlp_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_execlp_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_execlp_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_execlp_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_execlp_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_execlp_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_54d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_54d.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_54e_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_54d_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_54e_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_54d_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_system_42.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_system_42.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +static wchar_t * badSource(wchar_t * data) +{ + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + return data; +} + +void CWE78_OS_Command_Injection__wchar_t_console_system_42_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + data = badSource(data); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static wchar_t * goodG2BSource(wchar_t * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + data = goodG2BSource(data); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_system_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_11.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_11.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_11_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_05.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_05.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_05_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_popen_42.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_popen_42.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +static char * badSource(char * data) +{ + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + return data; +} + +void CWE78_OS_Command_Injection__char_listen_socket_popen_42_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + data = badSource(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static char * goodG2BSource(char * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + data = goodG2BSource(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_popen_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_popen_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_popen_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_execv_10.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_execv_10.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_execv_10_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_execv_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_execv_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_execv_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_system_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_system_08.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_system_08_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticReturnsTrue()) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_system_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_system_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_system_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_system_11.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_system_11.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_system_11_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_system_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_system_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_system_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_54d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_54d.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECVP _wexecvp + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_54e_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_54d_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_54e_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_54d_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_spawnlp_32.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnlp_32.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_32_bad() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + char * data = *dataPtr1; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + char * data = *dataPtr1; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnlp_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnlp_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_system_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_system_54a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_system_54b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_system_54_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + CWE78_OS_Command_Injection__wchar_t_console_system_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_system_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_console_system_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_console_system_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_system_10.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_system_10.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_system_10_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_system_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_system_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_system_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_09.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_09.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_09_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_execvp_66a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_execvp_66a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_w32_execvp_66b_badSink(char * dataArray[]); + +void CWE78_OS_Command_Injection__char_file_w32_execvp_66_bad() +{ + char * data; + char * dataArray[5]; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + /* put data in array */ + dataArray[2] = data; + CWE78_OS_Command_Injection__char_file_w32_execvp_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32_execvp_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + dataArray[2] = data; + CWE78_OS_Command_Injection__char_file_w32_execvp_66b_goodG2BSink(dataArray); +} + +void CWE78_OS_Command_Injection__char_file_w32_execvp_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_execvp_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_execvp_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_14.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_14.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_14_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_01.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_01.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_01_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32spawnl_10.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32spawnl_10.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32spawnl_10_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_console_w32spawnl_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32spawnl_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32spawnl_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_16.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_16.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_16_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + break; + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + break; + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_system_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_system_65a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: system + * BadSink : Execute command in data using system() + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_system_65b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_system_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_console_system_65b_badSink; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_system_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_console_system_65b_goodG2BSink; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_console_system_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_system_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_system_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_10.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_10.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_10_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execl_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64b_badSink(void * dataVoidPtr); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64b_goodG2BSink(&data); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_08_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_12.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_12.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_12_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_execlp_22b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_execlp_22b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE78_OS_Command_Injection__char_file_execlp_22_badGlobal; + +char * CWE78_OS_Command_Injection__char_file_execlp_22_badSource(char * data) +{ + if(CWE78_OS_Command_Injection__char_file_execlp_22_badGlobal) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE78_OS_Command_Injection__char_file_execlp_22_goodG2B1Global; +extern int CWE78_OS_Command_Injection__char_file_execlp_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_file_execlp_22_goodG2B1Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_file_execlp_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_file_execlp_22_goodG2B2Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_file_execlp_22_goodG2B2Global) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_06.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_06.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _execvp + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_06_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_execl_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_execl_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_execl_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_execl_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_execl_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_execl_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_execl_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_execl_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_execl_52b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execl_52b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_listen_socket_execl_52c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_listen_socket_execl_52b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_listen_socket_execl_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_listen_socket_execl_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_execl_52b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_listen_socket_execl_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_popen_22b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_popen_22b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE78_OS_Command_Injection__char_listen_socket_popen_22_badGlobal; + +char * CWE78_OS_Command_Injection__char_listen_socket_popen_22_badSource(char * data) +{ + if(CWE78_OS_Command_Injection__char_listen_socket_popen_22_badGlobal) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE78_OS_Command_Injection__char_listen_socket_popen_22_goodG2B1Global; +extern int CWE78_OS_Command_Injection__char_listen_socket_popen_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_listen_socket_popen_22_goodG2B1Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_listen_socket_popen_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_listen_socket_popen_22_goodG2B2Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_listen_socket_popen_22_goodG2B2Global) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_execlp_11.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execlp_11.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_execlp_11_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_environment_execlp_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_execlp_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_execlp_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_08_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_execv_65b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execv_65b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with execv + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_execv_65b_badSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_w32_execv_65b_goodG2BSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_system_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_system_54a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_system_54b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_system_54_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + CWE78_OS_Command_Injection__char_console_system_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_system_54b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_console_system_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_console_system_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_system_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_system_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_execlp_61b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execlp_61b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with execlp + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +char * CWE78_OS_Command_Injection__char_environment_execlp_61b_badSource(char * data) +{ + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char * CWE78_OS_Command_Injection__char_environment_execlp_61b_goodG2BSource(char * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_05.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_05.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_05_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_popen_51a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_popen_51a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_popen_51b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_popen_51_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__wchar_t_file_popen_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__wchar_t_file_popen_51b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_file_popen_51b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_file_popen_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_popen_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_popen_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_21.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_21.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static wchar_t * badSource(wchar_t * data) +{ + if(badStatic) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + return data; +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_21_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + badStatic = 1; /* true */ + data = badSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static wchar_t * goodG2B1Source(wchar_t * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static wchar_t * goodG2B2Source(wchar_t * data) +{ + if(goodG2B2Static) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _wexecv + +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_68_badData; +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_68b_badSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_68_badData; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_68b_goodG2BSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_68_goodG2BData; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_spawnvp_67a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnvp_67a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +typedef struct _CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_structType +{ + char * structFirst; +} CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_67b_badSink(CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_structType myStruct); + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_structType myStruct; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + myStruct.structFirst = data; + CWE78_OS_Command_Injection__char_file_w32_spawnvp_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_67b_goodG2BSink(CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_structType myStruct; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myStruct.structFirst = data; + CWE78_OS_Command_Injection__char_file_w32_spawnvp_67b_goodG2BSink(myStruct); +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnvp_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_execl_09.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_execl_09.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_execl_09_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_connect_socket_execl_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_execl_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_execl_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_spawnvp_54b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnvp_54b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_54c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_54b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_w32_spawnvp_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_54b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_w32_spawnvp_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_system_53c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_system_53c.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_system_53d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_system_53c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_system_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_system_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_system_53c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_system_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_07.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_07.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_07_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_spawnvp_64b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnvp_64b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_67b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_67b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +typedef struct _CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_67_structType +{ + wchar_t * structFirst; +} CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_67_structType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_67b_badSink(CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_67b_goodG2BSink(CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_execl_07.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_execl_07.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_execl_07_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_console_execl_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_execl_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_execl_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_execl_15.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_execl_15.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_execl_15_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + break; + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_file_execl_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_execl_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_execl_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _wexecvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_system_66a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_system_66a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: system + * BadSink : Execute command in data using system() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_system_66b_badSink(wchar_t * dataArray[]); + +void CWE78_OS_Command_Injection__wchar_t_environment_system_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* put data in array */ + dataArray[2] = data; + CWE78_OS_Command_Injection__wchar_t_environment_system_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_system_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + dataArray[2] = data; + CWE78_OS_Command_Injection__wchar_t_environment_system_66b_goodG2BSink(dataArray); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_system_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_system_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_system_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_execlp_04.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_execlp_04.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_execlp_04_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_console_execlp_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_execlp_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_execlp_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_06.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_06.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_06_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_execl_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_execl_53a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_execl_53b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_execl_53_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_execl_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_execl_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_execl_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_execl_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_execl_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_execl_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_09.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_09.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_09_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_spawnlp_53d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnlp_53d.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32_spawnlp_53d_badSink(char * data) +{ + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32_spawnlp_53d_goodG2BSink(char * data) +{ + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_21.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_21.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static char * badSource(char * data) +{ + if(badStatic) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + return data; +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_21_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + badStatic = 1; /* true */ + data = badSource(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static char * goodG2B1Source(char * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static char * goodG2B2Source(char * data) +{ + if(goodG2B2Static) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_execlp_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_execlp_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_execlp_08_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_console_execlp_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_execlp_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_execlp_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64b_badSink(void * dataVoidPtr); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64b_goodG2BSink(&data); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +static wchar_t * CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_badData; +static wchar_t * CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_badData; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_goodG2BData; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32spawnl_07.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32spawnl_07.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32spawnl_07_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_file_w32spawnl_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64b_badSink(void * dataVoidPtr); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64b_goodG2BSink(&data); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_execvp_31.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execvp_31.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_execvp_31_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + { + char * dataCopy = data; + char * data = dataCopy; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char * dataCopy = data; + char * data = dataCopy; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_execvp_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_execvp_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_execvp_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32spawnl_51a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32spawnl_51a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_w32spawnl_51b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_w32spawnl_51_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__char_file_w32spawnl_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__char_file_w32spawnl_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_file_w32spawnl_51b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_file_w32spawnl_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_67b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_67b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +typedef struct _CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_67_structType +{ + wchar_t * structFirst; +} CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_67_structType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_67b_badSink(CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_67b_goodG2BSink(CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32_execvp_22b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execvp_22b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE78_OS_Command_Injection__char_environment_w32_execvp_22_badGlobal; + +char * CWE78_OS_Command_Injection__char_environment_w32_execvp_22_badSource(char * data) +{ + if(CWE78_OS_Command_Injection__char_environment_w32_execvp_22_badGlobal) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B1Global; +extern int CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B1Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B2Source(char * data) +{ + if(CWE78_OS_Command_Injection__char_environment_w32_execvp_22_goodG2B2Global) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_53c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_53c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_53d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_53c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_53c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnlp_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _wexecv + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_08_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_badGlobal; + +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_badSource(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_badGlobal) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_goodG2B1Global; +extern int CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_goodG2B1Source(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_goodG2B2Source(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_22_goodG2B2Global) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_popen_53d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_popen_53d.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_popen_53d_badSink(char * data) +{ + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_popen_53d_goodG2BSink(char * data) +{ + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_spawnvp_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnvp_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_08_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnvp_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnvp_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_execv_13.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_execv_13.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execv_13_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execv_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execv_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execv_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_execlp_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execlp_53a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_execlp_53b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_environment_execlp_53_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__char_environment_execlp_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_environment_execlp_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_environment_execlp_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_environment_execlp_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_execlp_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_execlp_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_execl_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_execl_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: execl + * BadSink : execute command with execl + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_execl_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_execl_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-22a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +int CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_badGlobal = 0; + +char * CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_badSource(char * data); + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_badGlobal = 1; /* true */ + data = CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_badSource(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +int CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_goodG2B1Global = 0; +int CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_goodG2B2Global = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_goodG2B1Source(char * data); + +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_goodG2B1Global = 0; /* false */ + data = CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_goodG2B1Source(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_goodG2B2Source(char * data); + +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_goodG2B2Global = 1; /* true */ + data = CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_goodG2B2Source(data); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_execl_54b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_execl_54b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_execl_54c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_execl_54b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_execl_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_execl_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_execl_54b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_execl_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_03.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_03.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_03_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_07.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_07.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_07_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_execl_63a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execl_63a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: execl + * BadSink : execute command with execl + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_listen_socket_execl_63b_badSink(char * * dataPtr); + +void CWE78_OS_Command_Injection__char_listen_socket_execl_63_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_listen_socket_execl_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_execl_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_listen_socket_execl_63b_goodG2BSink(&data); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execl_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32spawnl_32.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32spawnl_32.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32spawnl_32_bad() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + char * data = *dataPtr1; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + char * data = *dataPtr1; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__char_console_w32spawnl_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32spawnl_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32spawnl_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_popen_66a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_popen_66a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_listen_socket_popen_66b_badSink(char * dataArray[]); + +void CWE78_OS_Command_Injection__char_listen_socket_popen_66_bad() +{ + char * data; + char * dataArray[5]; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* put data in array */ + dataArray[2] = data; + CWE78_OS_Command_Injection__char_listen_socket_popen_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_popen_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + dataArray[2] = data; + CWE78_OS_Command_Injection__char_listen_socket_popen_66b_goodG2BSink(dataArray); +} + +void CWE78_OS_Command_Injection__char_listen_socket_popen_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_popen_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_popen_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_51b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_51b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_51b_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_51b_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_18.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_18.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_18_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_execl_32.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_execl_32.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_execl_32_bad() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + wchar_t * data = *dataPtr1; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + wchar_t * data = *dataPtr1; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_execl_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_execl_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_execl_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_05.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_05.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECVP _wexecvp + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_05_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execvp_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_44.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_44.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnlp_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_popen_66a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_popen_66a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_popen_66b_badSink(wchar_t * dataArray[]); + +void CWE78_OS_Command_Injection__wchar_t_environment_popen_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* put data in array */ + dataArray[2] = data; + CWE78_OS_Command_Injection__wchar_t_environment_popen_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_popen_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + dataArray[2] = data; + CWE78_OS_Command_Injection__wchar_t_environment_popen_66b_goodG2BSink(dataArray); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_popen_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_popen_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_popen_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32spawnl_21.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32spawnl_21.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static char * badSource(char * data) +{ + if(badStatic) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + return data; +} + +void CWE78_OS_Command_Injection__char_file_w32spawnl_21_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + badStatic = 1; /* true */ + data = badSource(data); + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static char * goodG2B1Source(char * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static char * goodG2B2Source(char * data) +{ + if(goodG2B2Static) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + return data; +} + +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_file_w32spawnl_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_54c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_54d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_54c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_54c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_execl_67a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execl_67a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: execl + * BadSink : execute command with execl + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +typedef struct _CWE78_OS_Command_Injection__char_listen_socket_execl_67_structType +{ + char * structFirst; +} CWE78_OS_Command_Injection__char_listen_socket_execl_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_listen_socket_execl_67b_badSink(CWE78_OS_Command_Injection__char_listen_socket_execl_67_structType myStruct); + +void CWE78_OS_Command_Injection__char_listen_socket_execl_67_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_listen_socket_execl_67_structType myStruct; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myStruct.structFirst = data; + CWE78_OS_Command_Injection__char_listen_socket_execl_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_execl_67b_goodG2BSink(CWE78_OS_Command_Injection__char_listen_socket_execl_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_listen_socket_execl_67_structType myStruct; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myStruct.structFirst = data; + CWE78_OS_Command_Injection__char_listen_socket_execl_67b_goodG2BSink(myStruct); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execl_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_system_61b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_system_61b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: system + * BadSink : Execute command in data using system() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +char * CWE78_OS_Command_Injection__char_listen_socket_system_61b_badSource(char * data) +{ + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char * CWE78_OS_Command_Injection__char_listen_socket_system_61b_goodG2BSource(char * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_execlp_17.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execlp_17.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execlp_17_bad() +{ + int i; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execlp_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execlp_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execlp_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_67b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_67b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _execvp + +typedef struct _CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_67_structType +{ + char * structFirst; +} CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_67_structType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_67b_badSink(CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_67b_goodG2BSink(CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_popen_64b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_popen_64b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_popen_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_popen_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_execlp_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_execlp_54a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_execlp_54b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_execlp_54_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__char_file_execlp_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_file_execlp_54b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_file_execlp_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_file_execlp_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_execlp_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_execlp_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_32.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_32.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_32_bad() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + wchar_t * data = *dataPtr1; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + wchar_t * data = *dataPtr1; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnv_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_06.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_06.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_06_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_64b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_64b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_w32_spawnv_18.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnv_18.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32_spawnv_18_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_console_w32_spawnv_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnv_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnv_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_system_01.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_system_01.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_01_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_system_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_system_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68_badData; +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68b_badSink(); + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68_badData = data; + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68_goodG2BData = data; + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68b_goodG2BSink(); +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_68_badData; +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_68b_badSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_68_badData; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_68b_goodG2BSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_68_goodG2BData; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_popen_12.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_popen_12.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_popen_12_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalReturnsTrueOrFalse()) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__char_console_popen_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_popen_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_popen_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32spawnl_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_popen_44.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_popen_44.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_popen_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__wchar_t_console_popen_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_popen_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_popen_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_44.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_44.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_53c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_53c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _execvp + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_53d_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_53c_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_53d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_53c_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32_spawnv_45.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnv_45.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +static char * CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_badData; +static char * CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + char * data = CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_badData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_goodG2BData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61b_badSource(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61b_badSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61b_goodG2BSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_execlp_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_execlp_54c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_execlp_54d_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_execlp_54c_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_execlp_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_execlp_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_execlp_54c_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_execlp_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_execlp_03.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_execlp_03.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_execlp_03_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_file_execlp_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_execlp_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_execlp_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_52c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_52c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _wexecvp + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_52c_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_52c_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_64b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_64b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_execlp_09.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_execlp_09.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_execlp_09_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_console_execlp_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_execlp_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_execlp_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_03.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_03.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_03_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_execl_16.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_execl_16.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_execl_16_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_connect_socket_execl_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_execl_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_execl_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_execvp_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_execvp_54a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_execvp_54b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_w32_execvp_54_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + CWE78_OS_Command_Injection__char_console_w32_execvp_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_execvp_54b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_console_w32_execvp_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_console_w32_execvp_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_execvp_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_execvp_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_spawnvp_64b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnvp_64b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_spawnvp_18.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnvp_18.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_18_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnvp_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnvp_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_spawnv_04.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnv_04.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_04_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnv_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnv_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _wexecv + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_execlp_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_execlp_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_execlp_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_execlp_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_execlp_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_execlp_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_execlp_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_execlp_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54d.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54e_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54d_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54e_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54d_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_execlp_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_execlp_53a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_execlp_53b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_execlp_53_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__wchar_t_file_execlp_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_execlp_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_file_execlp_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_file_execlp_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_execlp_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_execlp_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_system_52c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_system_52c.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_system_52c_badSink(wchar_t * data) +{ + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_system_52c_goodG2BSink(wchar_t * data) +{ + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _wexecvp + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66b_badSink(wchar_t * dataArray[]); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* put data in array */ + dataArray[2] = data; + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + dataArray[2] = data; + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66b_goodG2BSink(dataArray); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_execlp_16.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execlp_16.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execlp_16_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + } + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execlp_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execlp_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execlp_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_01.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_01.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_01_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_popen_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_popen_54c.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_popen_54d_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_popen_54c_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_popen_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_popen_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_popen_54c_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_popen_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_execlp_51a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_execlp_51a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_execlp_51b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_51_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_execlp_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__char_connect_socket_execlp_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_execlp_51b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_execlp_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_execlp_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_execlp_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_system_10.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_system_10.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_system_10_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__char_console_system_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_system_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_system_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32spawnl_67b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32spawnl_67b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +typedef struct _CWE78_OS_Command_Injection__char_console_w32spawnl_67_structType +{ + char * structFirst; +} CWE78_OS_Command_Injection__char_console_w32spawnl_67_structType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32spawnl_67b_badSink(CWE78_OS_Command_Injection__char_console_w32spawnl_67_structType myStruct) +{ + char * data = myStruct.structFirst; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32spawnl_67b_goodG2BSink(CWE78_OS_Command_Injection__char_console_w32spawnl_67_structType myStruct) +{ + char * data = myStruct.structFirst; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_w32_execv_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_execv_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_53d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_53d.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_53d_badSink(wchar_t * data) +{ + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_53d_goodG2BSink(wchar_t * data) +{ + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_54c.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_54d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_54c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_54c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_31.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_31.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_31_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_execl_32.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_execl_32.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_execl_32_bad() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + wchar_t * data = *dataPtr1; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + wchar_t * data = *dataPtr1; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_execl_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_execl_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_execl_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_52b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_52b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_52c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_52b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_52c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_52b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_execv_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_system_01.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_system_01.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_system_01_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_system_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_system_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_system_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32spawnl_34.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32spawnl_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE78_OS_Command_Injection__char_console_w32spawnl_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32spawnl_34_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_console_w32spawnl_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_console_w32spawnl_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__char_console_w32spawnl_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32spawnl_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32spawnl_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_execv_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_execv_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _wexecv + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_execv_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_execv_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61b_badSource(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61b_badSource(data); + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61b_goodG2BSource(data); + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_spawnv_44.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnv_44.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnv_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnv_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_popen_17.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_popen_17.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_popen_17_bad() +{ + int i; + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + for(i = 0; i < 1; i++) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_popen_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_popen_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_popen_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_system_31.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_system_31.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: system + * BadSink : Execute command in data using system() + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_31_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_system_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_system_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_16.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_16.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_16_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + break; + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_execlp_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execlp_65a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with execlp + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_execlp_65b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_environment_execlp_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_environment_execlp_65b_badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_execlp_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_environment_execlp_65b_goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_environment_execlp_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_execlp_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_execlp_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_spawnlp_22a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnlp_22a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-22a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +int CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_badGlobal = 0; + +char * CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_badSource(char * data); + +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_badGlobal = 1; /* true */ + data = CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_badSource(data); + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +int CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_goodG2B1Global = 0; +int CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_goodG2B2Global = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_goodG2B1Source(char * data); + +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_goodG2B1Global = 0; /* false */ + data = CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_goodG2B1Source(data); + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_goodG2B2Source(char * data); + +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_goodG2B2Global = 1; /* true */ + data = CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_goodG2B2Source(data); + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnlp_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32spawnl_14.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32spawnl_14.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32spawnl_14_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive==5) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_file_w32spawnl_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_popen_13.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_popen_13.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_popen_13_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(GLOBAL_CONST_FIVE==5) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__char_environment_popen_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_popen_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_popen_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_08_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnlp_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _execvp + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_execl_02.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execl_02.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_execl_02_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(1) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_environment_execl_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_execl_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_execl_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_spawnvp_13.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnvp_13.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_13_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE==5) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnvp_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnvp_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_execlp_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_execlp_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_execlp_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_execlp_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_execlp_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_execlp_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_execlp_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_execlp_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +static char * CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_badData; +static char * CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + char * data = CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_badData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_goodG2BData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnvp_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_03.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_03.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_03_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_system_61a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_system_61a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: system + * BadSink : Execute command in data using system() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_system_61b_badSource(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_system_61_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + data = CWE78_OS_Command_Injection__wchar_t_console_system_61b_badSource(data); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_system_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + data = CWE78_OS_Command_Injection__wchar_t_console_system_61b_goodG2BSource(data); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_system_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_17.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_17.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_17_bad() +{ + int i; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execvp_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_spawnv_03.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnv_03.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_03_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_spawnlp_52c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnlp_52c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_52c_badSink(char * data) +{ + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_52c_goodG2BSink(char * data) +{ + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32spawnl_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32spawnl_65a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_w32spawnl_65b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_environment_w32spawnl_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_environment_w32spawnl_65b_badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_w32spawnl_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_environment_w32spawnl_65b_goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_environment_w32spawnl_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32spawnl_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32spawnl_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_01.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_01.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_01_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_spawnvp_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnvp_54c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_54d_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_54c_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_w32_spawnvp_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_54c_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_w32_spawnvp_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_06.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_06.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_06_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +extern char * CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_68_badData; +extern char * CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_68b_badSink() +{ + char * data = CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_68_badData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_68b_goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_68_goodG2BData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_system_02.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_system_02.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_system_02_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(1) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_system_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_system_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_system_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_51b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_51b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_51b_badSink(wchar_t * data) +{ + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_51b_goodG2BSink(wchar_t * data) +{ + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_02.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_02.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_02_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_65b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_65b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_65b_badSink(wchar_t * data) +{ + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_65b_goodG2BSink(wchar_t * data) +{ + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_17.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_17.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_17_bad() +{ + int i; + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnv_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_system_10.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_system_10.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_system_10_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_system_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_system_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_system_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +typedef struct _CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType +{ + wchar_t * structFirst; +} CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67b_badSink(CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67b_goodG2BSink(CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_execl_52c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_execl_52c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_execl_52c_badSink(wchar_t * data) +{ + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_execl_52c_goodG2BSink(wchar_t * data) +{ + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_09.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_09.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_09_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnv_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_system_05.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_system_05.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_system_05_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticTrue) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__char_environment_system_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_system_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_system_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_68_badData; +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_68b_badSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_68_badData; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_68b_goodG2BSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_68_goodG2BData; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_31.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_31.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_31_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +wchar_t * CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68_badData; +wchar_t * CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68b_badSink(); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68_badData = data; + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68_goodG2BData = data; + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68b_goodG2BSink(); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_18.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_18.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_18_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_65b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_65b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_65b_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_65b_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_system_14.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_system_14.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_system_14_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_system_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_system_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_system_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_spawnv_66a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnv_66a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_66b_badSink(char * dataArray[]); + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_66_bad() +{ + char * data; + char * dataArray[5]; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* put data in array */ + dataArray[2] = data; + CWE78_OS_Command_Injection__char_environment_w32_spawnv_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + dataArray[2] = data; + CWE78_OS_Command_Injection__char_environment_w32_spawnv_66b_goodG2BSink(dataArray); +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_popen_31.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_popen_31.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_popen_31_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + { + char * dataCopy = data; + char * data = dataCopy; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char * dataCopy = data; + char * data = dataCopy; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } + } +} + +void CWE78_OS_Command_Injection__char_environment_popen_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_popen_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_popen_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_spawnvp_52a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnvp_52a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_52b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_52_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + CWE78_OS_Command_Injection__char_console_w32_spawnvp_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_console_w32_spawnvp_52b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_console_w32_spawnvp_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnvp_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnvp_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_execlp_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execlp_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with execlp + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execlp_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_execlp_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_spawnvp_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnvp_65a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_65b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_file_w32_spawnvp_65b_badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_file_w32_spawnvp_65b_goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnvp_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnvp_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_execlp_64b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_execlp_64b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: execlp + * BadSink : execute command with execlp + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_execlp_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_execlp_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + /* execlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_01.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_01.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_01_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_54d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_54d.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_54e_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_54d_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_54e_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_54d_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65b_badSink; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65b_goodG2BSink; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_61b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_61b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_61b_badSource(wchar_t * data) +{ + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_61b_goodG2BSource(wchar_t * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32_spawnvp_52b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnvp_52b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_52c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_52b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_environment_w32_spawnvp_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_52b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_environment_w32_spawnvp_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_68_badData; +extern wchar_t * CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_68b_badSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_68_badData; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_68b_goodG2BSink() +{ + wchar_t * data = CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_68_goodG2BData; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_spawnvp_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnvp_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_53c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_53b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_file_w32_spawnvp_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_53c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32_spawnvp_53b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_file_w32_spawnvp_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_console_execl_51b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_execl_51b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_execl_51b_badSink(char * data) +{ + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_execl_51b_goodG2BSink(char * data) +{ + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_execl_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_execl_54a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_execl_54b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_execl_54_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__char_file_execl_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_file_execl_54b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_file_execl_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_file_execl_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_execl_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_execl_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECVP _wexecvp + +typedef struct _CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_structType +{ + wchar_t * structFirst; +} CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67b_badSink(CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_structType myStruct); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_bad() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_structType myStruct; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myStruct.structFirst = data; + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67b_goodG2BSink(CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_structType myStruct); + +static void goodG2B() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_structType myStruct; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + myStruct.structFirst = data; + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67b_goodG2BSink(myStruct); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execvp_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_16.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_16.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_16_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_execl_52a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_execl_52a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_execl_52b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_execl_52_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__wchar_t_environment_execl_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_execl_52b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_environment_execl_52b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_execl_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_execl_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_execl_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_execv_14.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_execv_14.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_execv_14_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive==5) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_execv_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_execv_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_execv_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_07.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_07.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_07_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnlp_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_execvp_12.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execvp_12.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_execvp_12_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_execvp_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_execvp_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_execvp_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_execvp_32.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_execvp_32.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include +#define EXECVP _wexecvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_execvp_32_bad() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + wchar_t * data = *dataPtr1; + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t * *dataPtr1 = &data; + wchar_t * *dataPtr2 = &data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + wchar_t * data = *dataPtr1; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + *dataPtr1 = data; + } + { + wchar_t * data = *dataPtr2; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_execvp_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_execvp_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_execvp_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_popen_42.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_popen_42.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +static char * badSource(char * data) +{ + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + return data; +} + +void CWE78_OS_Command_Injection__char_file_popen_42_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + data = badSource(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static char * goodG2BSource(char * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + data = goodG2BSource(data); + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__char_file_popen_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_popen_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_popen_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_execv_51a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_execv_51a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_execv_51b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_w32_execv_51_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + CWE78_OS_Command_Injection__char_console_w32_execv_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__char_console_w32_execv_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_console_w32_execv_51b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_console_w32_execv_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_execv_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_execv_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_system_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_system_66b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: system + * BadSink : Execute command in data using system() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_system_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_system_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_17.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_17.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_17_bad() +{ + int i; + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32spawnl_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_05.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_05.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_05_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_execv_52b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_execv_52b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _wexecv + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_52c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_52b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_execv_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_52c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_52b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_execv_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execv_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execv_68b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _execv + +extern char * CWE78_OS_Command_Injection__char_connect_socket_w32_execv_68_badData; +extern char * CWE78_OS_Command_Injection__char_connect_socket_w32_execv_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_68b_badSink() +{ + char * data = CWE78_OS_Command_Injection__char_connect_socket_w32_execv_68_badData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_68b_goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_connect_socket_w32_execv_68_goodG2BData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_popen_34.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_popen_34.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE78_OS_Command_Injection__char_connect_socket_popen_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_popen_34_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_connect_socket_popen_34_unionType myUnion; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_connect_socket_popen_34_unionType myUnion; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_popen_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_popen_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_popen_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_04.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_04.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _execvp + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_04_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_54e.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_54e.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_54e_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_54e_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_popen_67a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_popen_67a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +typedef struct _CWE78_OS_Command_Injection__char_file_popen_67_structType +{ + char * structFirst; +} CWE78_OS_Command_Injection__char_file_popen_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_popen_67b_badSink(CWE78_OS_Command_Injection__char_file_popen_67_structType myStruct); + +void CWE78_OS_Command_Injection__char_file_popen_67_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_file_popen_67_structType myStruct; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + myStruct.structFirst = data; + CWE78_OS_Command_Injection__char_file_popen_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_popen_67b_goodG2BSink(CWE78_OS_Command_Injection__char_file_popen_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_file_popen_67_structType myStruct; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myStruct.structFirst = data; + CWE78_OS_Command_Injection__char_file_popen_67b_goodG2BSink(myStruct); +} + +void CWE78_OS_Command_Injection__char_file_popen_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_popen_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_popen_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_spawnv_68a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnv_68a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +char * CWE78_OS_Command_Injection__char_environment_w32_spawnv_68_badData; +char * CWE78_OS_Command_Injection__char_environment_w32_spawnv_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_68b_badSink(); + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_68_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE78_OS_Command_Injection__char_environment_w32_spawnv_68_badData = data; + CWE78_OS_Command_Injection__char_environment_w32_spawnv_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_68_goodG2BData = data; + CWE78_OS_Command_Injection__char_environment_w32_spawnv_68b_goodG2BSink(); +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_execlp_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_execlp_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_execlp_53c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_execlp_53b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_file_execlp_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_file_execlp_53c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_execlp_53b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_file_execlp_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_system_52b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_system_52b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_system_52c_badSink(char * data); + +void CWE78_OS_Command_Injection__char_environment_system_52b_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_environment_system_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_environment_system_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_system_52b_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_environment_system_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_52c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_52c.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_52c_badSink(wchar_t * data) +{ + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_52c_goodG2BSink(wchar_t * data) +{ + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_system_10.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_system_10.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_system_10_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_system_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_21.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_21.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static wchar_t * badSource(wchar_t * data) +{ + if(badStatic) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + return data; +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_21_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + badStatic = 1; /* true */ + data = badSource(data); + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static wchar_t * goodG2B1Source(wchar_t * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static wchar_t * goodG2B2Source(wchar_t * data) +{ + if(goodG2B2Static) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_popen_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_popen_66b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_popen_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_popen_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32spawnl_06.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32spawnl_06.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32spawnl_06_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_file_w32spawnl_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32spawnl_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32spawnl_11.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32spawnl_11.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32spawnl_11_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_console_w32spawnl_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32spawnl_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32spawnl_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_18.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_18.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_18_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execlp_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_16.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_16.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_16_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + break; + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + while(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + break; + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32spawnl_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65b_badSink; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65b_goodG2BSink; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_execvp_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_execvp_54c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECVP _execvp + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_execvp_54d_badSink(char * data); + +void CWE78_OS_Command_Injection__char_console_w32_execvp_54c_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_w32_execvp_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_console_w32_execvp_54d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32_execvp_54c_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_console_w32_execvp_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_execl_18.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_execl_18.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_execl_18_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_file_execl_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_execl_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_execl_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_execv_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_execv_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with execv + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execv_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_w32_execv_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_system_07.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_system_07.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_system_07_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_system_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_system_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_system_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32spawnl_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_popen_10.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_popen_10.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_popen_10_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_popen_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_popen_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_popen_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61b_badSource(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61b_badSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61b_goodG2BSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_execv_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_execv_67b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execv_67b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with execv + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include +#define EXECV _execv + +typedef struct _CWE78_OS_Command_Injection__char_environment_w32_execv_67_structType +{ + char * structFirst; +} CWE78_OS_Command_Injection__char_environment_w32_execv_67_structType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_execv_67b_badSink(CWE78_OS_Command_Injection__char_environment_w32_execv_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_w32_execv_67b_goodG2BSink(CWE78_OS_Command_Injection__char_environment_w32_execv_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_execl_34.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execl_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: execl + * BadSink : execute command with execl + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE78_OS_Command_Injection__char_listen_socket_execl_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execl_34_bad() +{ + char * data; + CWE78_OS_Command_Injection__char_listen_socket_execl_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE78_OS_Command_Injection__char_listen_socket_execl_34_unionType myUnion; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_execl_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53a.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34_bad() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34_unionType myUnion; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34_unionType myUnion; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_04.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_04.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_04_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnv_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_execlp_53a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_execlp_53a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with execlp + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECLP _execlp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_execlp_53b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_execlp_53_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__char_file_execlp_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_file_execlp_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_file_execlp_53b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_file_execlp_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_execlp_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_execlp_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_spawnlp_12.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_spawnlp_12.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32_spawnlp_12_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_console_w32_spawnlp_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnlp_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_spawnlp_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_execv_61b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_execv_61b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with execv + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +char * CWE78_OS_Command_Injection__char_file_w32_execv_61b_badSource(char * data) +{ + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char * CWE78_OS_Command_Injection__char_file_w32_execv_61b_goodG2BSource(char * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_spawnlp_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_system_22b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_system_22b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE78_OS_Command_Injection__wchar_t_console_system_22_badGlobal; + +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_system_22_badSource(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_console_system_22_badGlobal) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE78_OS_Command_Injection__wchar_t_console_system_22_goodG2B1Global; +extern int CWE78_OS_Command_Injection__wchar_t_console_system_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_system_22_goodG2B1Source(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_console_system_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE78_OS_Command_Injection__wchar_t_console_system_22_goodG2B2Source(wchar_t * data) +{ + if(CWE78_OS_Command_Injection__wchar_t_console_system_22_goodG2B2Global) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_64b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_64b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnv_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_popen_04.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_popen_04.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_popen_04_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(STATIC_CONST_TRUE) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + if(STATIC_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__char_environment_popen_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_popen_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_popen_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_execl_41.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execl_41.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execl_41_badSink(char * data) +{ + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execl_41_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_listen_socket_execl_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE78_OS_Command_Injection__char_listen_socket_execl_41_goodG2BSink(char * data) +{ + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_listen_socket_execl_41_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execl_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34_unionType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34_bad() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34_unionType myUnion; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34_unionType myUnion; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + /* wspawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnlp_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_54c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_54c.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_54d_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_54c_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_54d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_54c_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_connect_socket_popen_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32spawnl_52c.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32spawnl_52c.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32spawnl_52c_badSink(char * data) +{ + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32spawnl_52c_goodG2BSink(char * data) +{ + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECV _wexecv + +typedef struct _CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType +{ + wchar_t * structFirst; +} CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67b_badSink(CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType myStruct); + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_bad() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType myStruct; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + myStruct.structFirst = data; + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67b_goodG2BSink(CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType myStruct); + +static void goodG2B() +{ + wchar_t * data; + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_structType myStruct; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + myStruct.structFirst = data; + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67b_goodG2BSink(myStruct); +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_execv_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_spawnvp_61b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnvp_61b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +char * CWE78_OS_Command_Injection__char_environment_w32_spawnvp_61b_badSource(char * data) +{ + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char * CWE78_OS_Command_Injection__char_environment_w32_spawnvp_61b_goodG2BSource(char * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + return data; +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_system_02.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_system_02.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_system_02_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(1) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_system_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_system_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_system_16.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_system_16.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM _wsystem +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_16_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + while(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + while(1) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + break; + } + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_system_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_system_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_system_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32_spawnv_15.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnv_15.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_15_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_spawnv_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_spawnv_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_popen_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_popen_68b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _popen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +extern char * CWE78_OS_Command_Injection__char_listen_socket_popen_68_badData; +extern char * CWE78_OS_Command_Injection__char_listen_socket_popen_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_popen_68b_badSink() +{ + char * data = CWE78_OS_Command_Injection__char_listen_socket_popen_68_badData; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_popen_68b_goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_listen_socket_popen_68_goodG2BData; + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, ""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_system_68b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_system_68b.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +extern char * CWE78_OS_Command_Injection__char_listen_socket_system_68_badData; +extern char * CWE78_OS_Command_Injection__char_listen_socket_system_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_system_68b_badSink() +{ + char * data = CWE78_OS_Command_Injection__char_listen_socket_system_68_badData; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_system_68b_goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_listen_socket_system_68_goodG2BData; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + if (SYSTEM(data) != 0) + { + printLine(""command execution failed!""); + exit(1); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execv_17.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execv_17.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_17_bad() +{ + int i; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execv_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execv_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_44.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_44.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_spawnv + * BadSink : execute command with wspawnv + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_spawnv_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_execv_65a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execv_65a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with execv + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_environment_w32_execv_65b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_environment_w32_execv_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_environment_w32_execv_65b_badSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_w32_execv_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE78_OS_Command_Injection__char_environment_w32_execv_65b_goodG2BSink; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + funcPtr(data); +} + +void CWE78_OS_Command_Injection__char_environment_w32_execv_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_execv_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_execv_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_execv_17.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_execv_17.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32_execv_17_bad() +{ + int i; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_console_w32_execv_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_execv_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_execv_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_execl_41.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_execl_41.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_execl_41_badSink(char * data) +{ + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_console_execl_41_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + CWE78_OS_Command_Injection__char_console_execl_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE78_OS_Command_Injection__char_console_execl_41_goodG2BSink(char * data) +{ + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_console_execl_41_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_console_execl_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_execl_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_execl_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_execv_45.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_execv_45.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with execv + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _execv + +static char * CWE78_OS_Command_Injection__char_console_w32_execv_45_badData; +static char * CWE78_OS_Command_Injection__char_console_w32_execv_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + char * data = CWE78_OS_Command_Injection__char_console_w32_execv_45_badData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_console_w32_execv_45_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + CWE78_OS_Command_Injection__char_console_w32_execv_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char * data = CWE78_OS_Command_Injection__char_console_w32_execv_45_goodG2BData; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_console_w32_execv_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE78_OS_Command_Injection__char_console_w32_execv_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_console_w32_execv_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_console_w32_execv_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_execl_12.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_execl_12.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with execl + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECL _execl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_execl_12_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* execl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_listen_socket_execl_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_execl_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_67b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_67b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +typedef struct _CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_67_structType +{ + char * structFirst; +} CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_67_structType; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_67b_badSink(CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_67b_goodG2BSink(CWE78_OS_Command_Injection__char_connect_socket_w32_spawnvp_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32_execv_18.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execv_18.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_execv_18_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goto source; +source: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_execv_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_execv_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_execv_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_listen_socket_w32_execvp_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_10.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_10.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECVP _wexecvp + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_10_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + { + /* Read input from the console */ + size_t dataLen = wcslen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgetws() */ + dataLen = wcslen(data); + if (dataLen > 0 && data[dataLen-1] == L'\n') + { + data[dataLen-1] = L'\0'; + } + } + else + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_console_w32_execvp_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_12.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_12.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_12_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_popen_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_execlp_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_execlp_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_execlp_08_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_file_execlp_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_execlp_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_execlp_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_execvp_52a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_execvp_52a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include +#define EXECVP _execvp + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_file_w32_execvp_52b_badSink(char * data); + +void CWE78_OS_Command_Injection__char_file_w32_execvp_52_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__char_file_w32_execvp_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_file_w32_execvp_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_file_w32_execvp_52b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_file_w32_execvp_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_execvp_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_execvp_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_execlp_54b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_execlp_54b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_execlp_54c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_execlp_54b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_execlp_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_execlp_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_execlp_54b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_execlp_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_15.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_15.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_15_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + break; + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_66b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_66b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with spawnl + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_w32spawnl_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + /* spawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_environment_w32_spawnvp_64b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_spawnvp_64b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_environment_w32_spawnvp_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_spawnlp_51b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnlp_51b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_51b_badSink(char * data) +{ + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_51b_goodG2BSink(char * data) +{ + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54e.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54e.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _wexecv + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54e_badSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_54e_goodG2BSink(wchar_t * data) +{ + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_31.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_31.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sinks: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_31_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + char * dataCopy = data; + char * data = dataCopy; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + { + char * dataCopy = data; + char * data = dataCopy; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51b_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51b_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execv_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sinks: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32spawnl_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68_badData; +wchar_t * CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68b_badSink(); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68_badData = data; + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68_goodG2BData = data; + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68b_goodG2BSink(); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_system_54d.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_system_54d.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-54d.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: system + * BadSink : Execute command in data using system() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND ""dir "" +#else +#include +#define FULL_COMMAND ""ls "" +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#define SYSTEM system +#else /* NOT _WIN32 */ +#define SYSTEM system +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_system_54e_badSink(char * data); + +void CWE78_OS_Command_Injection__char_connect_socket_system_54d_badSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_system_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__char_connect_socket_system_54e_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_connect_socket_system_54d_goodG2BSink(char * data) +{ + CWE78_OS_Command_Injection__char_connect_socket_system_54e_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_file_w32_spawnv_08.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnv_08.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_08_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticReturnsTrue()) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnv_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnv_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_54b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_54b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with wexecvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECVP _wexecvp + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_54c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_54b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_54b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_execvp_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_05.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_05.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_05_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnv_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41_badSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41_goodG2BSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41_goodG2BSink(data); +} + +void CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_connect_socket_w32_execv_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_spawnv_51b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnv_51b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnv + * BadSink : execute command with spawnv + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnv_51b_badSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_file_w32_spawnv_51b_goodG2BSink(char * data) +{ + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnv(_P_WAIT, COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_42.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_42.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with wexecv + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#include +#define EXECV _wexecv + +#ifndef OMITBAD + +static wchar_t * badSource(wchar_t * data) +{ + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + return data; +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_42_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = badSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static wchar_t * goodG2BSource(wchar_t * data) +{ + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + data = goodG2BSource(data); + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wexecv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_execv_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_10.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_10.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: execlp + * BadSink : execute command with wexeclp + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#ifdef _WIN32 +#include +#define EXECLP _wexeclp +#else /* NOT _WIN32 */ +#define EXECLP execlp +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_10_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(globalTrue) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wexeclp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECLP(COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_listen_socket_execlp_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_07.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_07.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32spawnl + * BadSink : execute command with wspawnl + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_07_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + /* wspawnl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnl(_P_WAIT, COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32spawnl_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_execv_17.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_execv_17.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_execv + * BadSink : execute command with execv + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execv_17_bad() +{ + int i; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + for(h = 0; h < 1; h++) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_execv_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execv_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_execv_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_21.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_21.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Fixed string + * Sink: execl + * BadSink : execute command with wexecl + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" + +#ifdef _WIN32 +#include +#define EXECL _wexecl +#else /* NOT _WIN32 */ +#define EXECL execl +#endif + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static wchar_t * badSource(wchar_t * data) +{ + if(badStatic) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + wchar_t *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = wcslen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; + /* Eliminate CRLF */ + replace = wcschr(data, L'\r'); + if (replace) + { + *replace = L'\0'; + } + replace = wcschr(data, L'\n'); + if (replace) + { + *replace = L'\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + return data; +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_21_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + badStatic = 1; /* true */ + data = badSource(data); + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static wchar_t * goodG2B1Source(wchar_t * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static wchar_t * goodG2B2Source(wchar_t * data) +{ + if(goodG2B2Static) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + return data; +} + +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + /* wexecl - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECL(COMMAND_INT_PATH, COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_connect_socket_execl_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_03.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_03.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_03_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(5==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* wspawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _wspawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnvp_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_file_w32_spawnlp_06.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_file_w32_spawnlp_06.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sink: w32_spawnlp + * BadSink : execute command with spawnlp + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_06_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + { + /* Read input from a file */ + size_t dataLen = strlen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgets(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgets() failed""); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + fclose(pFile); + } + } + } + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + /* spawnlp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnlp(_P_WAIT, COMMAND_INT, COMMAND_INT, COMMAND_ARG1, COMMAND_ARG3, NULL); +} + +void CWE78_OS_Command_Injection__char_file_w32_spawnlp_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnlp_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_file_w32_spawnlp_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_console_w32_execv_63b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_console_w32_execv_63b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: console Read input from the console + * GoodSource: Fixed string + * Sinks: w32_execv + * BadSink : execute command with execv + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#include +#define EXECV _execv + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_console_w32_execv_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__char_console_w32_execv_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execv - specify the path where the command is located */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECV(COMMAND_INT_PATH, args); + } +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_54b.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_54b.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with wspawnvp + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_54c_badSink(wchar_t * data); + +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_54b_badSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_54b_goodG2BSink(wchar_t * data) +{ + CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE78_OS_Command_Injection__wchar_t_environment_popen_09.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_environment_popen_09.c +Label Definition File: CWE78_OS_Command_Injection.one_string.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: popen + * BadSink : Execute command in data using popen() + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define FULL_COMMAND L""dir "" +#else +#include +#define FULL_COMMAND L""ls "" +#endif + +#define ENV_VARIABLE L""ADD"" + +#ifdef _WIN32 +#define GETENV _wgetenv +#else +#define GETENV getenv +#endif + +/* define POPEN as _popen on Windows and popen otherwise */ +#ifdef _WIN32 +#define POPEN _wpopen +#define PCLOSE _pclose +#else /* NOT _WIN32 */ +#define POPEN popen +#define PCLOSE pclose +#endif + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__wchar_t_environment_popen_09_bad() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(GLOBAL_CONST_TRUE) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = wcslen(data); + wchar_t * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + wcsncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + wchar_t data_buf[100] = FULL_COMMAND; + data = data_buf; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + } + { + FILE *pipe; + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection */ + pipe = POPEN(data, L""w""); + if (pipe != NULL) + { + PCLOSE(pipe); + } + } +} + +void CWE78_OS_Command_Injection__wchar_t_environment_popen_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_environment_popen_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_environment_popen_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_environment_w32_execvp_07.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_environment_w32_execvp_07.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: environment Read input from an environment variable + * GoodSource: Fixed string + * Sink: w32_execvp + * BadSink : execute command with execvp + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#define ENV_VARIABLE ""ADD"" + +#ifdef _WIN32 +#define GETENV getenv +#else +#define GETENV getenv +#endif + +#include +#define EXECVP _execvp + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_environment_w32_execvp_07_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + if(staticFive==5) + { + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* execvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + EXECVP(COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_environment_w32_execvp_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_environment_w32_execvp_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_environment_w32_execvp_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63a.c,CWE78,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63a.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: file Read input from a file + * GoodSource: Fixed string + * Sinks: w32_spawnlp + * BadSink : execute command with wspawnlp + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH L""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT L""cmd.exe"" +#define COMMAND_ARG1 L""/c"" +#define COMMAND_ARG2 L""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH L""/bin/sh"" +#define COMMAND_INT L""sh"" +#define COMMAND_ARG1 L""-c"" +#define COMMAND_ARG2 L""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#define FILENAME ""C:\\temp\\file.txt"" +#else +#define FILENAME ""/tmp/file.txt"" +#endif + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63b_badSink(wchar_t * * dataPtr); + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63_bad() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + { + /* Read input from a file */ + size_t dataLen = wcslen(data); + FILE * pFile; + /* if there is room in data, attempt to read the input from a file */ + if (100-dataLen > 1) + { + pFile = fopen(FILENAME, ""r""); + if (pFile != NULL) + { + /* POTENTIAL FLAW: Read data from a file */ + if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) + { + printLine(""fgetws() failed""); + /* Restore NUL terminator if fgetws fails */ + data[dataLen] = L'\0'; + } + fclose(pFile); + } + } + } + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63b_goodG2BSink(wchar_t * * data); + +static void goodG2B() +{ + wchar_t * data; + wchar_t dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + /* FIX: Append a fixed string to data (not user / external input) */ + wcscat(data, L""*.*""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63b_goodG2BSink(&data); +} + +void CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__wchar_t_file_w32_spawnlp_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_15.c,CWE78,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_15.c +Label Definition File: CWE78_OS_Command_Injection.strings.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 78 OS Command Injection + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Fixed string + * Sink: w32_spawnvp + * BadSink : execute command with spawnvp + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define COMMAND_INT_PATH ""%WINDIR%\\system32\\cmd.exe"" +#define COMMAND_INT ""cmd.exe"" +#define COMMAND_ARG1 ""/c"" +#define COMMAND_ARG2 ""dir "" +#define COMMAND_ARG3 data +#else /* NOT _WIN32 */ +#include +#define COMMAND_INT_PATH ""/bin/sh"" +#define COMMAND_INT ""sh"" +#define COMMAND_ARG1 ""-c"" +#define COMMAND_ARG2 ""ls "" +#define COMMAND_ARG3 data +#endif + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 + +#include + +#ifndef OMITBAD + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_15_bad() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + char * data; + char dataBuffer[100] = COMMAND_ARG2; + data = dataBuffer; + switch(6) + { + case 6: + /* FIX: Append a fixed string to data (not user / external input) */ + strcat(data, ""*.*""); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + char *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG3, NULL}; + /* spawnvp - searches for the location of the command among + * the directories specified by the PATH environment variable */ + /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ + _spawnvp(_P_WAIT, COMMAND_INT, args); + } +} + +void CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE78_OS_Command_Injection__char_listen_socket_w32_spawnvp_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_square_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_square_63a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_fscanf_square_63b_badSink(short * dataPtr); + +void CWE190_Integer_Overflow__short_fscanf_square_63_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_square_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_square_63b_goodG2BSink(short * data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__short_fscanf_square_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_square_63b_goodB2GSink(short * data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_square_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__short_fscanf_square_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_square_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_square_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_add_34.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_add_34.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +typedef union +{ + int64_t unionFirst; + int64_t unionSecond; +} CWE190_Integer_Overflow__int64_t_max_add_34_unionType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_add_34_bad() +{ + int64_t data; + CWE190_Integer_Overflow__int64_t_max_add_34_unionType myUnion; + data = 0LL; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + CWE190_Integer_Overflow__int64_t_max_add_34_unionType myUnion; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + CWE190_Integer_Overflow__int64_t_max_add_34_unionType myUnion; + data = 0LL; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int64_t_max_add_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_add_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_add_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_32.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_32.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_preinc_32_bad() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + *dataPtr1 = data; + } + { + char data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + char data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + *dataPtr1 = data; + } + { + char data = *dataPtr2; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_preinc_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_square_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_square_65a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_max_square_65b_badSink(char data); + +void CWE190_Integer_Overflow__char_max_square_65_bad() +{ + char data; + /* define a function pointer */ + void (*funcPtr) (char) = CWE190_Integer_Overflow__char_max_square_65b_badSink; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_square_65b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + void (*funcPtr) (char) = CWE190_Integer_Overflow__char_max_square_65b_goodG2BSink; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_square_65b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + void (*funcPtr) (char) = CWE190_Integer_Overflow__char_max_square_65b_goodB2GSink; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + funcPtr(data); +} + +void CWE190_Integer_Overflow__char_max_square_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_square_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_square_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_add_51b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_add_51b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_add_51b_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_add_51b_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_add_51b_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_max_multiply_44.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_multiply_44.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_max_multiply_44_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = badSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = goodB2GSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + funcPtr(data); +} + +void CWE190_Integer_Overflow__int_max_multiply_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_multiply_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_multiply_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_square_22b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_square_22b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE190_Integer_Overflow__int_connect_socket_square_22_badGlobal; + +void CWE190_Integer_Overflow__int_connect_socket_square_22_badSink(int data) +{ + if(CWE190_Integer_Overflow__int_connect_socket_square_22_badGlobal) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G1Global; +extern int CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G2Global; +extern int CWE190_Integer_Overflow__int_connect_socket_square_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G1Sink(int data) +{ + if(CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G2Sink(int data) +{ + if(CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__int_connect_socket_square_22_goodG2BSink(int data) +{ + if(CWE190_Integer_Overflow__int_connect_socket_square_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fgets_multiply_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_multiply_13.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_multiply_13_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_multiply_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_multiply_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_multiply_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_add_14.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_add_14.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_14_bad() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_add_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_add_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_square_22a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_square_22a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-22a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +int CWE190_Integer_Overflow__int_connect_socket_square_22_badGlobal = 0; + +void CWE190_Integer_Overflow__int_connect_socket_square_22_badSink(int data); + +void CWE190_Integer_Overflow__int_connect_socket_square_22_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_square_22_badGlobal = 1; /* true */ + CWE190_Integer_Overflow__int_connect_socket_square_22_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +int CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G1Global = 0; +int CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G2Global = 0; +int CWE190_Integer_Overflow__int_connect_socket_square_22_goodG2BGlobal = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G1Sink(int data); + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G1Global = 0; /* false */ + CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G2Sink(int data); + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G2Global = 1; /* true */ + CWE190_Integer_Overflow__int_connect_socket_square_22_goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__int_connect_socket_square_22_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_connect_socket_square_22_goodG2BGlobal = 1; /* true */ + CWE190_Integer_Overflow__int_connect_socket_square_22_goodG2BSink(data); +} + +void CWE190_Integer_Overflow__int_connect_socket_square_22_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_square_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_square_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_add_12.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_add_12.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_add_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + else + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_add_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_add_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_add_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_square_10.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_square_10.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_square_10_bad() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(globalTrue) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_square_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_square_06.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_square_06.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_square_06_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_square_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_square_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_square_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_square_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_square_61b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +short CWE190_Integer_Overflow__short_max_square_61b_badSource(short data) +{ + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +short CWE190_Integer_Overflow__short_max_square_61b_goodG2BSource(short data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +short CWE190_Integer_Overflow__short_max_square_61b_goodB2GSource(short data) +{ + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_rand_multiply_06.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_multiply_06.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_multiply_06_bad() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_rand_multiply_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_multiply_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_multiply_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_multiply_06.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_multiply_06.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_06_bad() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_add_53a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_add_53a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_rand_add_53b_badSink(int data); + +void CWE190_Integer_Overflow__int_rand_add_53_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + CWE190_Integer_Overflow__int_rand_add_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_add_53b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_rand_add_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_add_53b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + CWE190_Integer_Overflow__int_rand_add_53b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int_rand_add_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_add_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_add_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_multiply_13.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_multiply_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_multiply_13_bad() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_multiply_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_multiply_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_multiply_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_add_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_add_54c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_rand_add_54d_badSink(char data); + +void CWE190_Integer_Overflow__char_rand_add_54c_badSink(char data) +{ + CWE190_Integer_Overflow__char_rand_add_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_rand_add_54d_goodG2BSink(char data); + +void CWE190_Integer_Overflow__char_rand_add_54c_goodG2BSink(char data) +{ + CWE190_Integer_Overflow__char_rand_add_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_rand_add_54d_goodB2GSink(char data); + +void CWE190_Integer_Overflow__char_rand_add_54c_goodB2GSink(char data) +{ + CWE190_Integer_Overflow__char_rand_add_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_connect_socket_multiply_11.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_multiply_11.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_multiply_11_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_connect_socket_multiply_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_multiply_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_multiply_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_postinc_41.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_postinc_41.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(char data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } +} + +void CWE190_Integer_Overflow__char_rand_postinc_41_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + goodB2GSink(data); +} + +void CWE190_Integer_Overflow__char_rand_postinc_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_postinc_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_postinc_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_multiply_64a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_multiply_64a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_connect_socket_multiply_64b_badSink(void * dataVoidPtr); + +void CWE190_Integer_Overflow__int_connect_socket_multiply_64_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_multiply_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_multiply_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_connect_socket_multiply_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_multiply_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_multiply_64b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int_connect_socket_multiply_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_multiply_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_multiply_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_postinc_09.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_postinc_09.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_09_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_postinc_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_postinc_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_preinc_07.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_preinc_07.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-07.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + any other value so a tool should be able to identify that reads of + this will always give its initialized value. */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_07_bad() +{ + int64_t data; + data = 0LL; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticFive==5 to staticFive!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(staticFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_07_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_multiply_12.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_multiply_12.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_multiply_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + else + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalReturnsTrueOrFalse()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_multiply_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_add_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_add_51a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_rand_add_51b_badSink(int data); + +void CWE190_Integer_Overflow__int_rand_add_51_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + CWE190_Integer_Overflow__int_rand_add_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_add_51b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_rand_add_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_add_51b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + CWE190_Integer_Overflow__int_rand_add_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int_rand_add_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_add_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_add_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_postinc_54e.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_postinc_54e.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_54e_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_54e_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_54e_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_add_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_08.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_add_08_bad() +{ + unsigned int data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_add_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_multiply_67b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_multiply_67b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE190_Integer_Overflow__char_rand_multiply_67_structType +{ + char structFirst; +} CWE190_Integer_Overflow__char_rand_multiply_67_structType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_multiply_67b_badSink(CWE190_Integer_Overflow__char_rand_multiply_67_structType myStruct) +{ + char data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_rand_multiply_67b_goodG2BSink(CWE190_Integer_Overflow__char_rand_multiply_67_structType myStruct) +{ + char data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_rand_multiply_67b_goodB2GSink(CWE190_Integer_Overflow__char_rand_multiply_67_structType myStruct) +{ + char data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_rand_postinc_14.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_postinc_14.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_postinc_14_bad() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_rand_postinc_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_postinc_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_postinc_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_postinc_03.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_postinc_03.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_postinc_03_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_connect_socket_postinc_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_postinc_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_postinc_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_preinc_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_preinc_63b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_preinc_63b_badSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_rand_preinc_63b_goodG2BSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_rand_preinc_63b_goodB2GSink(char * dataPtr) +{ + char data = *dataPtr; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +unsigned int CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_badData; +unsigned int CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_goodG2BData; +unsigned int CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68b_badSink(); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_badData = data; + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68b_goodG2BSink(); +void CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_goodG2BData = data; + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_goodB2GData = data; + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68b_goodB2GSink(); +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_add_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_54c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_54d_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_add_54c_badSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_add_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_54d_goodG2BSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_add_54c_goodG2BSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_add_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_54d_goodB2GSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_add_54c_goodB2GSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_add_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_add_53c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_add_53c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_add_53d_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_add_53c_badSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_fscanf_add_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_add_53d_goodG2BSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_add_53c_goodG2BSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_fscanf_add_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_add_53d_goodB2GSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_add_53c_goodB2GSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_fscanf_add_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_05.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_05.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_05_bad() +{ + unsigned int data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(staticTrue) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_square_53a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_square_53a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_rand_square_53b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_square_53_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE190_Integer_Overflow__int64_t_rand_square_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_rand_square_53b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_rand_square_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_rand_square_53b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE190_Integer_Overflow__int64_t_rand_square_53b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int64_t_rand_square_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_square_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_square_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_add_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_add_08.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_add_08_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_add_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_add_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_add_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_square_64a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_square_64a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_listen_socket_square_64b_badSink(void * dataVoidPtr); + +void CWE190_Integer_Overflow__int_listen_socket_square_64_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_listen_socket_square_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_listen_socket_square_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_listen_socket_square_64b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int_listen_socket_square_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_square_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_square_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_preinc_32.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_preinc_32.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_preinc_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_preinc_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_preinc_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_preinc_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_max_multiply_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_multiply_52c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_max_multiply_52c_badSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_max_multiply_52c_goodG2BSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_max_multiply_52c_goodB2GSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_max_preinc_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_preinc_63b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_preinc_63b_badSink(int64_t * dataPtr) +{ + int64_t data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_preinc_63b_goodG2BSink(int64_t * dataPtr) +{ + int64_t data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_preinc_63b_goodB2GSink(int64_t * dataPtr) +{ + int64_t data = *dataPtr; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_fscanf_postinc_21.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_postinc_21.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(char data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_postinc_21_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(char data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(char data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(char data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__char_fscanf_postinc_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_postinc_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_postinc_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_multiply_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_multiply_68b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern char CWE190_Integer_Overflow__char_fscanf_multiply_68_badData; +extern char CWE190_Integer_Overflow__char_fscanf_multiply_68_goodG2BData; +extern char CWE190_Integer_Overflow__char_fscanf_multiply_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_multiply_68b_badSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_multiply_68_badData; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_fscanf_multiply_68b_goodG2BSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_multiply_68_goodG2BData; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_fscanf_multiply_68b_goodB2GSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_multiply_68_goodB2GData; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_max_add_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_add_51a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_max_add_51b_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_max_add_51_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + CWE190_Integer_Overflow__unsigned_int_max_add_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_max_add_51b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_max_add_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_max_add_51b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + CWE190_Integer_Overflow__unsigned_int_max_add_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__unsigned_int_max_add_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_add_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_add_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_multiply_18.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_multiply_18.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_multiply_18_bad() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + goto sink; +sink: + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + goto sink; +sink: + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goto sink; +sink: + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +void CWE190_Integer_Overflow__int64_t_rand_multiply_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_multiply_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_multiply_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52b_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_multiply_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_multiply_65a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fscanf_multiply_65b_badSink(int data); + +void CWE190_Integer_Overflow__int_fscanf_multiply_65_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_fscanf_multiply_65b_badSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_multiply_65b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_fscanf_multiply_65b_goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_multiply_65b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_fscanf_multiply_65b_goodB2GSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + funcPtr(data); +} + +void CWE190_Integer_Overflow__int_fscanf_multiply_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_multiply_31.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_multiply_31.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_multiply_31_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + { + char dataCopy = data; + char data = dataCopy; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + { + char dataCopy = data; + char data = dataCopy; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + { + char dataCopy = data; + char data = dataCopy; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +void CWE190_Integer_Overflow__char_rand_multiply_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_multiply_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_multiply_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_postinc_14.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_postinc_14.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_postinc_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_postinc_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_postinc_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_postinc_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_postinc_03.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_postinc_03.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_postinc_03_bad() +{ + short data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__short_max_postinc_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_postinc_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_postinc_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_postinc_54b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_postinc_54b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_max_postinc_54c_badSink(char data); + +void CWE190_Integer_Overflow__char_max_postinc_54b_badSink(char data) +{ + CWE190_Integer_Overflow__char_max_postinc_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_postinc_54c_goodG2BSink(char data); + +void CWE190_Integer_Overflow__char_max_postinc_54b_goodG2BSink(char data) +{ + CWE190_Integer_Overflow__char_max_postinc_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_postinc_54c_goodB2GSink(char data); + +void CWE190_Integer_Overflow__char_max_postinc_54b_goodB2GSink(char data) +{ + CWE190_Integer_Overflow__char_max_postinc_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fgets_square_32.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_square_32.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_square_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_square_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_square_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_square_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_square_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_square_61b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +char CWE190_Integer_Overflow__char_fscanf_square_61b_badSource(char data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char CWE190_Integer_Overflow__char_fscanf_square_61b_goodG2BSource(char data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +char CWE190_Integer_Overflow__char_fscanf_square_61b_goodB2GSource(char data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_max_square_66b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_square_66b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_square_66b_badSink(int dataArray[]) +{ + /* copy data out of dataArray */ + int data = dataArray[2]; + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_max_square_66b_goodG2BSink(int dataArray[]) +{ + int data = dataArray[2]; + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_max_square_66b_goodB2GSink(int dataArray[]) +{ + int data = dataArray[2]; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fgets_square_06.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_square_06.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_square_06_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_square_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_square_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_square_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_postinc_12.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_postinc_12.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_12_bad() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + else + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_postinc_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_postinc_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_add_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_add_08.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_add_08_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_add_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_add_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_add_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_preinc_17.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_preinc_17.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_preinc_17_bad() +{ + int i,j; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int data; + /* Initialize data */ + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_preinc_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_preinc_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_preinc_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_preinc_06.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_preinc_06.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_preinc_06_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_preinc_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_preinc_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_preinc_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_add_18.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_add_18.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_add_18_bad() +{ + short data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + goto sink; +sink: + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + short data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + goto sink; +sink: + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + short result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + short data; + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__short_fscanf_add_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_add_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_add_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_multiply_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_multiply_63a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_63b_badSink(int64_t * dataPtr); + +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_63_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%lld"", &data); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_63b_goodG2BSink(int64_t * data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_fscanf_multiply_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_63b_goodB2GSink(int64_t * data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%lld"", &data); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_square_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_square_08.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_square_08_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_connect_socket_square_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_square_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_square_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_add_22b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_add_22b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE190_Integer_Overflow__char_rand_add_22_badGlobal; + +void CWE190_Integer_Overflow__char_rand_add_22_badSink(char data) +{ + if(CWE190_Integer_Overflow__char_rand_add_22_badGlobal) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE190_Integer_Overflow__char_rand_add_22_goodB2G1Global; +extern int CWE190_Integer_Overflow__char_rand_add_22_goodB2G2Global; +extern int CWE190_Integer_Overflow__char_rand_add_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__char_rand_add_22_goodB2G1Sink(char data) +{ + if(CWE190_Integer_Overflow__char_rand_add_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__char_rand_add_22_goodB2G2Sink(char data) +{ + if(CWE190_Integer_Overflow__char_rand_add_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__char_rand_add_22_goodG2BSink(char data) +{ + if(CWE190_Integer_Overflow__char_rand_add_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_fscanf_square_18.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_square_18.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_square_18_bad() +{ + char data; + data = ' '; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goto sink; +sink: + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + char data; + data = ' '; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goto sink; +sink: + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + char data; + data = ' '; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goto sink; +sink: + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +void CWE190_Integer_Overflow__char_fscanf_square_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_square_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_square_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_multiply_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_multiply_51a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_rand_multiply_51b_badSink(char data); + +void CWE190_Integer_Overflow__char_rand_multiply_51_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE190_Integer_Overflow__char_rand_multiply_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_rand_multiply_51b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_rand_multiply_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_rand_multiply_51b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE190_Integer_Overflow__char_rand_multiply_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__char_rand_multiply_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_multiply_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_multiply_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_postinc_61a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_postinc_61a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +short CWE190_Integer_Overflow__short_rand_postinc_61b_badSource(short data); + +void CWE190_Integer_Overflow__short_rand_postinc_61_bad() +{ + short data; + data = 0; + data = CWE190_Integer_Overflow__short_rand_postinc_61b_badSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +short CWE190_Integer_Overflow__short_rand_postinc_61b_goodG2BSource(short data); + +static void goodG2B() +{ + short data; + data = 0; + data = CWE190_Integer_Overflow__short_rand_postinc_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +short CWE190_Integer_Overflow__short_rand_postinc_61b_goodB2GSource(short data); + +static void goodB2G() +{ + short data; + data = 0; + data = CWE190_Integer_Overflow__short_rand_postinc_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__short_rand_postinc_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_postinc_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_postinc_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_square_66a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_square_66a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_66b_badSink(int64_t dataArray[]); + +void CWE190_Integer_Overflow__int64_t_fscanf_square_66_bad() +{ + int64_t data; + int64_t dataArray[5]; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + /* put data in array */ + dataArray[2] = data; + CWE190_Integer_Overflow__int64_t_fscanf_square_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_66b_goodG2BSink(int64_t dataArray[]); + +static void goodG2B() +{ + int64_t data; + int64_t dataArray[5]; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + dataArray[2] = data; + CWE190_Integer_Overflow__int64_t_fscanf_square_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_66b_goodB2GSink(int64_t dataArray[]); + +static void goodB2G() +{ + int64_t data; + int64_t dataArray[5]; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + dataArray[2] = data; + CWE190_Integer_Overflow__int64_t_fscanf_square_66b_goodB2GSink(dataArray); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_square_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_postinc_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_postinc_63b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_postinc_63b_badSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_fscanf_postinc_63b_goodG2BSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_fscanf_postinc_63b_goodB2GSink(char * dataPtr) +{ + char data = *dataPtr; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_listen_socket_preinc_53d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_preinc_53d.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_preinc_53d_badSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_preinc_53d_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_preinc_53d_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_fscanf_postinc_14.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_postinc_14.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_postinc_14_bad() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__short_fscanf_postinc_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_postinc_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_postinc_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_square_42.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_42.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static unsigned int badSource(unsigned int data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + return data; +} + +void CWE190_Integer_Overflow__unsigned_int_rand_square_42_bad() +{ + unsigned int data; + data = 0; + data = badSource(data); + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static unsigned int goodG2BSource(unsigned int data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +static void goodG2B() +{ + unsigned int data; + data = 0; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static unsigned int goodB2GSource(unsigned int data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + return data; +} + +static void goodB2G() +{ + unsigned int data; + data = 0; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_square_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_preinc_61a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_preinc_61a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE190_Integer_Overflow__int_max_preinc_61b_badSource(int data); + +void CWE190_Integer_Overflow__int_max_preinc_61_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_max_preinc_61b_badSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE190_Integer_Overflow__int_max_preinc_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_max_preinc_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE190_Integer_Overflow__int_max_preinc_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_max_preinc_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__int_max_preinc_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_preinc_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_preinc_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_postinc_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_postinc_65a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_max_postinc_65b_badSink(short data); + +void CWE190_Integer_Overflow__short_max_postinc_65_bad() +{ + short data; + /* define a function pointer */ + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_postinc_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_postinc_65b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_postinc_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_postinc_65b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_postinc_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + funcPtr(data); +} + +void CWE190_Integer_Overflow__short_max_postinc_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_postinc_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_postinc_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_square_66b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_square_66b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_square_66b_badSink(char dataArray[]) +{ + /* copy data out of dataArray */ + char data = dataArray[2]; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_square_66b_goodG2BSink(char dataArray[]) +{ + char data = dataArray[2]; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_square_66b_goodB2GSink(char dataArray[]) +{ + char data = dataArray[2]; + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_listen_socket_square_53b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_square_53b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-53b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_listen_socket_square_53c_badSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_square_53b_badSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_square_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_53c_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_square_53b_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_square_53c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_53c_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_square_53b_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_square_53c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_square_34.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_square_34.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +typedef union +{ + int64_t unionFirst; + int64_t unionSecond; +} CWE190_Integer_Overflow__int64_t_fscanf_square_34_unionType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_square_34_bad() +{ + int64_t data; + CWE190_Integer_Overflow__int64_t_fscanf_square_34_unionType myUnion; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + CWE190_Integer_Overflow__int64_t_fscanf_square_34_unionType myUnion; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + CWE190_Integer_Overflow__int64_t_fscanf_square_34_unionType myUnion; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_square_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_multiply_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_multiply_65a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_rand_multiply_65b_badSink(int data); + +void CWE190_Integer_Overflow__int_rand_multiply_65_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_rand_multiply_65b_badSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_multiply_65b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_rand_multiply_65b_goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_multiply_65b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_rand_multiply_65b_goodB2GSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + funcPtr(data); +} + +void CWE190_Integer_Overflow__int_rand_multiply_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_multiply_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_multiply_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_square_61a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_61a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_square_61b_badSource(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_square_61_bad() +{ + unsigned int data; + data = 0; + data = CWE190_Integer_Overflow__unsigned_int_rand_square_61b_badSource(data); + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_square_61b_goodG2BSource(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + data = CWE190_Integer_Overflow__unsigned_int_rand_square_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_square_61b_goodB2GSource(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + data = CWE190_Integer_Overflow__unsigned_int_rand_square_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_square_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_add_16.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_add_16.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_add_16_bad() +{ + int64_t data; + data = 0LL; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__int64_t_rand_add_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_add_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_add_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_add_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_add_61b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +char CWE190_Integer_Overflow__char_rand_add_61b_badSource(char data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char CWE190_Integer_Overflow__char_rand_add_61b_goodG2BSource(char data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +char CWE190_Integer_Overflow__char_rand_add_61b_goodB2GSource(char data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_max_multiply_32.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_multiply_32.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_multiply_32_bad() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +void CWE190_Integer_Overflow__int64_t_max_multiply_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_multiply_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_multiply_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_preinc_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_preinc_63a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_63b_badSink(int64_t * dataPtr); + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_63_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_63b_goodG2BSink(int64_t * data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_fscanf_preinc_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_63b_goodB2GSink(int64_t * data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_multiply_64b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_multiply_64b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_multiply_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_multiply_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_multiply_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_fscanf_square_12.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_square_12.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_12_bad() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + else + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_multiply_65b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_multiply_65b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_multiply_65b_badSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_rand_multiply_65b_goodG2BSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_rand_multiply_65b_goodB2GSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_fscanf_add_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_add_63b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_63b_badSink(unsigned int * dataPtr) +{ + unsigned int data = *dataPtr; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_63b_goodG2BSink(unsigned int * dataPtr) +{ + unsigned int data = *dataPtr; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_63b_goodB2GSink(unsigned int * dataPtr) +{ + unsigned int data = *dataPtr; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_square_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_square_51a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_51b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_square_51_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_square_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_51b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_fscanf_square_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_51b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_square_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_square_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_add_18.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_add_18.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_add_18_bad() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + goto sink; +sink: + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + goto sink; +sink: + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_fgets_add_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_add_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_add_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_multiply_06.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_multiply_06.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_multiply_06_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_multiply_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_64b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_64b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_max_multiply_02.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_multiply_02.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_multiply_02_bad() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_max_multiply_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_multiply_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_multiply_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_multiply_02.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_multiply_02.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_02_bad() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_21.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_21.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(char data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_preinc_21_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(char data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(char data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(char data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__char_fscanf_preinc_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_postinc_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_postinc_51a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fgets_postinc_51b_badSink(int data); + +void CWE190_Integer_Overflow__int_fgets_postinc_51_bad() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE190_Integer_Overflow__int_fgets_postinc_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fgets_postinc_51b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fgets_postinc_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fgets_postinc_51b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE190_Integer_Overflow__int_fgets_postinc_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int_fgets_postinc_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_postinc_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_postinc_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_square_12.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_square_12.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_square_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + else + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_square_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_square_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_square_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_multiply_67b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_multiply_67b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef struct _CWE190_Integer_Overflow__int_fgets_multiply_67_structType +{ + int structFirst; +} CWE190_Integer_Overflow__int_fgets_multiply_67_structType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_multiply_67b_badSink(CWE190_Integer_Overflow__int_fgets_multiply_67_structType myStruct) +{ + int data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fgets_multiply_67b_goodG2BSink(CWE190_Integer_Overflow__int_fgets_multiply_67_structType myStruct) +{ + int data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fgets_multiply_67b_goodB2GSink(CWE190_Integer_Overflow__int_fgets_multiply_67_structType myStruct) +{ + int data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fgets_multiply_10.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_multiply_10.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_multiply_10_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_multiply_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_multiply_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_multiply_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_add_45.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_add_45.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static char CWE190_Integer_Overflow__char_fscanf_add_45_badData; +static char CWE190_Integer_Overflow__char_fscanf_add_45_goodG2BData; +static char CWE190_Integer_Overflow__char_fscanf_add_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_add_45_badData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +void CWE190_Integer_Overflow__char_fscanf_add_45_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE190_Integer_Overflow__char_fscanf_add_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_add_45_goodG2BData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_fscanf_add_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_add_45_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE190_Integer_Overflow__char_fscanf_add_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE190_Integer_Overflow__char_fscanf_add_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_add_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_add_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_square_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_square_51a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_connect_socket_square_51b_badSink(int data); + +void CWE190_Integer_Overflow__int_connect_socket_square_51_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_square_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_square_51b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_connect_socket_square_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_square_51b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_square_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int_connect_socket_square_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_square_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_square_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_square_16.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_square_16.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_square_16_bad() +{ + short data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: if (data*data) > SHRT_MAX, this will overflow */ + short result = data * data; + printIntLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + short data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)SHRT_MAX)) + { + short result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + short data; + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: if (data*data) > SHRT_MAX, this will overflow */ + short result = data * data; + printIntLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__short_max_square_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_square_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_square_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_square_02.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_02.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_square_02_bad() +{ + unsigned int data; + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_square_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_postinc_22a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_postinc_22a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-22a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +int CWE190_Integer_Overflow__short_fscanf_postinc_22_badGlobal = 0; + +void CWE190_Integer_Overflow__short_fscanf_postinc_22_badSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_postinc_22_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_postinc_22_badGlobal = 1; /* true */ + CWE190_Integer_Overflow__short_fscanf_postinc_22_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +int CWE190_Integer_Overflow__short_fscanf_postinc_22_goodB2G1Global = 0; +int CWE190_Integer_Overflow__short_fscanf_postinc_22_goodB2G2Global = 0; +int CWE190_Integer_Overflow__short_fscanf_postinc_22_goodG2BGlobal = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__short_fscanf_postinc_22_goodB2G1Sink(short data); + +static void goodB2G1() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_postinc_22_goodB2G1Global = 0; /* false */ + CWE190_Integer_Overflow__short_fscanf_postinc_22_goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__short_fscanf_postinc_22_goodB2G2Sink(short data); + +static void goodB2G2() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_postinc_22_goodB2G2Global = 1; /* true */ + CWE190_Integer_Overflow__short_fscanf_postinc_22_goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__short_fscanf_postinc_22_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__short_fscanf_postinc_22_goodG2BGlobal = 1; /* true */ + CWE190_Integer_Overflow__short_fscanf_postinc_22_goodG2BSink(data); +} + +void CWE190_Integer_Overflow__short_fscanf_postinc_22_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_postinc_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_postinc_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_preinc_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_preinc_61b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +int CWE190_Integer_Overflow__int_max_preinc_61b_badSource(int data) +{ + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +int CWE190_Integer_Overflow__int_max_preinc_61b_goodG2BSource(int data) +{ + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +int CWE190_Integer_Overflow__int_max_preinc_61b_goodB2GSource(int data) +{ + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_max_preinc_54a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_preinc_54a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_preinc_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_preinc_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_multiply_02.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_multiply_02.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_multiply_02_bad() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_multiply_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_multiply_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_multiply_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_preinc_61a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_preinc_61a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE190_Integer_Overflow__int_connect_socket_preinc_61b_badSource(int data); + +void CWE190_Integer_Overflow__int_connect_socket_preinc_61_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_connect_socket_preinc_61b_badSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE190_Integer_Overflow__int_connect_socket_preinc_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_connect_socket_preinc_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE190_Integer_Overflow__int_connect_socket_preinc_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_connect_socket_preinc_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__int_connect_socket_preinc_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_preinc_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_preinc_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_add_21.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_add_21.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(char data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_max_add_21_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(char data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(char data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(char data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__char_max_add_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_add_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_add_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_add_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_add_68b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern char CWE190_Integer_Overflow__char_max_add_68_badData; +extern char CWE190_Integer_Overflow__char_max_add_68_goodG2BData; +extern char CWE190_Integer_Overflow__char_max_add_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_add_68b_badSink() +{ + char data = CWE190_Integer_Overflow__char_max_add_68_badData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_add_68b_goodG2BSink() +{ + char data = CWE190_Integer_Overflow__char_max_add_68_goodG2BData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_add_68b_goodB2GSink() +{ + char data = CWE190_Integer_Overflow__char_max_add_68_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_max_add_18.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_add_18.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_add_18_bad() +{ + char data; + data = ' '; + goto source; +source: + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + goto sink; +sink: + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + char data; + data = ' '; + goto source; +source: + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + goto sink; +sink: + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + char data; + data = ' '; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +void CWE190_Integer_Overflow__char_max_add_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_add_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_add_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_preinc_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_preinc_63a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_63b_badSink(int * dataPtr); + +void CWE190_Integer_Overflow__int_connect_socket_preinc_63_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_preinc_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_63b_goodG2BSink(int * data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_connect_socket_preinc_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_63b_goodB2GSink(int * data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_preinc_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int_connect_socket_preinc_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_preinc_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_preinc_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_max_add_11.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_add_11.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_max_add_11_bad() +{ + unsigned int data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_max_add_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_add_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_add_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_65b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_65b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_65b_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_65b_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_65b_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_add_42.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_add_42.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static int64_t badSource(int64_t data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + return data; +} + +void CWE190_Integer_Overflow__int64_t_fscanf_add_42_bad() +{ + int64_t data; + data = 0LL; + data = badSource(data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static int64_t goodG2BSource(int64_t data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static int64_t goodB2GSource(int64_t data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + return data; +} + +static void goodB2G() +{ + int64_t data; + data = 0LL; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_add_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_add_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_add_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_preinc_21.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_preinc_21.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_preinc_21_bad() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__int_fgets_preinc_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_preinc_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_preinc_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_postinc_22a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_postinc_22a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-22a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +int CWE190_Integer_Overflow__int_fscanf_postinc_22_badGlobal = 0; + +void CWE190_Integer_Overflow__int_fscanf_postinc_22_badSink(int data); + +void CWE190_Integer_Overflow__int_fscanf_postinc_22_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_postinc_22_badGlobal = 1; /* true */ + CWE190_Integer_Overflow__int_fscanf_postinc_22_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +int CWE190_Integer_Overflow__int_fscanf_postinc_22_goodB2G1Global = 0; +int CWE190_Integer_Overflow__int_fscanf_postinc_22_goodB2G2Global = 0; +int CWE190_Integer_Overflow__int_fscanf_postinc_22_goodG2BGlobal = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__int_fscanf_postinc_22_goodB2G1Sink(int data); + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_postinc_22_goodB2G1Global = 0; /* false */ + CWE190_Integer_Overflow__int_fscanf_postinc_22_goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__int_fscanf_postinc_22_goodB2G2Sink(int data); + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_postinc_22_goodB2G2Global = 1; /* true */ + CWE190_Integer_Overflow__int_fscanf_postinc_22_goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_22_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fscanf_postinc_22_goodG2BGlobal = 1; /* true */ + CWE190_Integer_Overflow__int_fscanf_postinc_22_goodG2BSink(data); +} + +void CWE190_Integer_Overflow__int_fscanf_postinc_22_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_square_51b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_square_51b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_square_51b_badSink(char data) +{ + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_rand_square_51b_goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_rand_square_51b_goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_max_multiply_64a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_multiply_64a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_max_multiply_64b_badSink(void * dataVoidPtr); + +void CWE190_Integer_Overflow__char_max_multiply_64_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + CWE190_Integer_Overflow__char_max_multiply_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_multiply_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_max_multiply_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_multiply_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + CWE190_Integer_Overflow__char_max_multiply_64b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__char_max_multiply_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_multiply_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_multiply_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_add_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_add_54c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_rand_add_54d_badSink(short data); + +void CWE190_Integer_Overflow__short_rand_add_54c_badSink(short data) +{ + CWE190_Integer_Overflow__short_rand_add_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_rand_add_54d_goodG2BSink(short data); + +void CWE190_Integer_Overflow__short_rand_add_54c_goodG2BSink(short data) +{ + CWE190_Integer_Overflow__short_rand_add_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_rand_add_54d_goodB2GSink(short data); + +void CWE190_Integer_Overflow__short_rand_add_54c_goodB2GSink(short data) +{ + CWE190_Integer_Overflow__short_rand_add_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_fscanf_multiply_54e.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_multiply_54e.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_multiply_54e_badSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_multiply_54e_goodG2BSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_multiply_54e_goodB2GSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (SHRT_MAX/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_max_square_31.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_square_31.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_square_31_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + { + int dataCopy = data; + int data = dataCopy; + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + { + int dataCopy = data; + int data = dataCopy; + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + { + int dataCopy = data; + int data = dataCopy; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_max_square_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_square_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_square_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_68b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern char CWE190_Integer_Overflow__char_fscanf_preinc_68_badData; +extern char CWE190_Integer_Overflow__char_fscanf_preinc_68_goodG2BData; +extern char CWE190_Integer_Overflow__char_fscanf_preinc_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_preinc_68b_badSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_preinc_68_badData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_fscanf_preinc_68b_goodG2BSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_preinc_68_goodG2BData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_fscanf_preinc_68b_goodB2GSink() +{ + char data = CWE190_Integer_Overflow__char_fscanf_preinc_68_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_postinc_64a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_postinc_64a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fscanf_postinc_64b_badSink(void * dataVoidPtr); + +void CWE190_Integer_Overflow__int_fscanf_postinc_64_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_postinc_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fscanf_postinc_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_postinc_64b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int_fscanf_postinc_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_postinc_21.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_postinc_21.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_postinc_21_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__int_rand_postinc_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_postinc_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_postinc_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_preinc_42.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_preinc_42.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static int badSource(int data) +{ + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + return data; +} + +void CWE190_Integer_Overflow__int_fgets_preinc_42_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = badSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static int goodG2BSource(int data) +{ + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + return data; +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static int goodB2GSource(int data) +{ + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + return data; +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__int_fgets_preinc_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_preinc_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_preinc_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_postinc_12.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_postinc_12.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_postinc_12_bad() +{ + char data; + data = ' '; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + else + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_rand_postinc_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_postinc_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_postinc_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_add_16.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_16.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_add_16_bad() +{ + unsigned int data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + unsigned int data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + unsigned int data; + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_add_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_add_41.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_add_41.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_max_add_41_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int_max_add_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_add_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_add_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_postinc_67b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_postinc_67b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE190_Integer_Overflow__int64_t_fscanf_postinc_67_structType +{ + int64_t structFirst; +} CWE190_Integer_Overflow__int64_t_fscanf_postinc_67_structType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_67b_badSink(CWE190_Integer_Overflow__int64_t_fscanf_postinc_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_67b_goodG2BSink(CWE190_Integer_Overflow__int64_t_fscanf_postinc_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_67b_goodB2GSink(CWE190_Integer_Overflow__int64_t_fscanf_postinc_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_connect_socket_multiply_01.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_multiply_01.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_multiply_01_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_connect_socket_multiply_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_multiply_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_multiply_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_postinc_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_postinc_54c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_rand_postinc_54d_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_postinc_54c_badSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_rand_postinc_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_rand_postinc_54d_goodG2BSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_postinc_54c_goodG2BSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_rand_postinc_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_rand_postinc_54d_goodB2GSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_postinc_54c_goodB2GSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_rand_postinc_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_rand_postinc_17.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_postinc_17.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_postinc_17_bad() +{ + int i,j; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int data; + /* Initialize data */ + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_postinc_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_postinc_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_postinc_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_multiply_66a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_multiply_66a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_max_multiply_66b_badSink(int dataArray[]); + +void CWE190_Integer_Overflow__int_max_multiply_66_bad() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + /* put data in array */ + dataArray[2] = data; + CWE190_Integer_Overflow__int_max_multiply_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_max_multiply_66b_goodG2BSink(int dataArray[]); + +static void goodG2B() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + dataArray[2] = data; + CWE190_Integer_Overflow__int_max_multiply_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_max_multiply_66b_goodB2GSink(int dataArray[]); + +static void goodB2G() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + dataArray[2] = data; + CWE190_Integer_Overflow__int_max_multiply_66b_goodB2GSink(dataArray); +} + +void CWE190_Integer_Overflow__int_max_multiply_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_multiply_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_multiply_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_multiply_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_multiply_61b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +short CWE190_Integer_Overflow__short_fscanf_multiply_61b_badSource(short data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +short CWE190_Integer_Overflow__short_fscanf_multiply_61b_goodG2BSource(short data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +short CWE190_Integer_Overflow__short_fscanf_multiply_61b_goodB2GSource(short data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_rand_square_03.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_square_03.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_square_03_bad() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5==5) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_square_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_square_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_square_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_square_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_square_63b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_square_63b_badSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_square_63b_goodG2BSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_square_63b_goodB2GSink(char * dataPtr) +{ + char data = *dataPtr; + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_max_multiply_68a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_multiply_68a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +char CWE190_Integer_Overflow__char_max_multiply_68_badData; +char CWE190_Integer_Overflow__char_max_multiply_68_goodG2BData; +char CWE190_Integer_Overflow__char_max_multiply_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_max_multiply_68b_badSink(); + +void CWE190_Integer_Overflow__char_max_multiply_68_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + CWE190_Integer_Overflow__char_max_multiply_68_badData = data; + CWE190_Integer_Overflow__char_max_multiply_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE190_Integer_Overflow__char_max_multiply_68b_goodG2BSink(); +void CWE190_Integer_Overflow__char_max_multiply_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_max_multiply_68_goodG2BData = data; + CWE190_Integer_Overflow__char_max_multiply_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + CWE190_Integer_Overflow__char_max_multiply_68_goodB2GData = data; + CWE190_Integer_Overflow__char_max_multiply_68b_goodB2GSink(); +} + +void CWE190_Integer_Overflow__char_max_multiply_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_multiply_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_multiply_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_add_45.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_add_45.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static int64_t CWE190_Integer_Overflow__int64_t_max_add_45_badData; +static int64_t CWE190_Integer_Overflow__int64_t_max_add_45_goodG2BData; +static int64_t CWE190_Integer_Overflow__int64_t_max_add_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_max_add_45_badData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +void CWE190_Integer_Overflow__int64_t_max_add_45_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + CWE190_Integer_Overflow__int64_t_max_add_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_max_add_45_goodG2BData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_max_add_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_max_add_45_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + CWE190_Integer_Overflow__int64_t_max_add_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE190_Integer_Overflow__int64_t_max_add_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_add_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_add_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_postinc_16.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_postinc_16.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_postinc_16_bad() +{ + char data; + data = ' '; + while(1) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + char data; + data = ' '; + while(1) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + char data; + data = ' '; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__char_fscanf_postinc_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_postinc_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_postinc_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_add_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_add_65a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_rand_add_65b_badSink(char data); + +void CWE190_Integer_Overflow__char_rand_add_65_bad() +{ + char data; + /* define a function pointer */ + void (*funcPtr) (char) = CWE190_Integer_Overflow__char_rand_add_65b_badSink; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_rand_add_65b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + void (*funcPtr) (char) = CWE190_Integer_Overflow__char_rand_add_65b_goodG2BSink; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_rand_add_65b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + void (*funcPtr) (char) = CWE190_Integer_Overflow__char_rand_add_65b_goodB2GSink; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + funcPtr(data); +} + +void CWE190_Integer_Overflow__char_rand_add_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_add_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_add_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_multiply_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_multiply_63a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_rand_multiply_63b_badSink(short * dataPtr); + +void CWE190_Integer_Overflow__short_rand_multiply_63_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE190_Integer_Overflow__short_rand_multiply_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_rand_multiply_63b_goodG2BSink(short * data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__short_rand_multiply_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_rand_multiply_63b_goodB2GSink(short * data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE190_Integer_Overflow__short_rand_multiply_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__short_rand_multiply_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_multiply_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_multiply_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_preinc_31.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_preinc_31.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_preinc_31_bad() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + { + int dataCopy = data; + int data = dataCopy; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + { + int dataCopy = data; + int data = dataCopy; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + { + int dataCopy = data; + int data = dataCopy; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_preinc_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_preinc_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_preinc_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_square_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_square_52c.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_square_52c_badSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_52c_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_52c_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_rand_preinc_18.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_preinc_18.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_preinc_18_bad() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goto sink; +sink: + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goto sink; +sink: + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_rand_preinc_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_preinc_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_preinc_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_postinc_67a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_postinc_67a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef struct _CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType +{ + int structFirst; +} CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_67b_badSink(CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct); + +void CWE190_Integer_Overflow__int_connect_socket_postinc_67_bad() +{ + int data; + CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myStruct.structFirst = data; + CWE190_Integer_Overflow__int_connect_socket_postinc_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_67b_goodG2BSink(CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct); + +static void goodG2B() +{ + int data; + CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + myStruct.structFirst = data; + CWE190_Integer_Overflow__int_connect_socket_postinc_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_67b_goodB2GSink(CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct); + +static void goodB2G() +{ + int data; + CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myStruct.structFirst = data; + CWE190_Integer_Overflow__int_connect_socket_postinc_67b_goodB2GSink(myStruct); +} + +void CWE190_Integer_Overflow__int_connect_socket_postinc_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_postinc_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_postinc_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_square_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_68b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +extern unsigned int CWE190_Integer_Overflow__unsigned_int_rand_square_68_badData; +extern unsigned int CWE190_Integer_Overflow__unsigned_int_rand_square_68_goodG2BData; +extern unsigned int CWE190_Integer_Overflow__unsigned_int_rand_square_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_square_68b_badSink() +{ + unsigned int data = CWE190_Integer_Overflow__unsigned_int_rand_square_68_badData; + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_68b_goodG2BSink() +{ + unsigned int data = CWE190_Integer_Overflow__unsigned_int_rand_square_68_goodG2BData; + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_68b_goodB2GSink() +{ + unsigned int data = CWE190_Integer_Overflow__unsigned_int_rand_square_68_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_fscanf_postinc_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_postinc_54c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_fscanf_postinc_54d_badSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_postinc_54c_badSink(short data) +{ + CWE190_Integer_Overflow__short_fscanf_postinc_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_postinc_54d_goodG2BSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_postinc_54c_goodG2BSink(short data) +{ + CWE190_Integer_Overflow__short_fscanf_postinc_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_postinc_54d_goodB2GSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_postinc_54c_goodB2GSink(short data) +{ + CWE190_Integer_Overflow__short_fscanf_postinc_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_max_multiply_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_multiply_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_max_multiply_13_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_max_multiply_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_multiply_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_multiply_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_preinc_68a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_preinc_68a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +int CWE190_Integer_Overflow__int_connect_socket_preinc_68_badData; +int CWE190_Integer_Overflow__int_connect_socket_preinc_68_goodG2BData; +int CWE190_Integer_Overflow__int_connect_socket_preinc_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_68b_badSink(); + +void CWE190_Integer_Overflow__int_connect_socket_preinc_68_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_preinc_68_badData = data; + CWE190_Integer_Overflow__int_connect_socket_preinc_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_68b_goodG2BSink(); +void CWE190_Integer_Overflow__int_connect_socket_preinc_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_connect_socket_preinc_68_goodG2BData = data; + CWE190_Integer_Overflow__int_connect_socket_preinc_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_preinc_68_goodB2GData = data; + CWE190_Integer_Overflow__int_connect_socket_preinc_68b_goodB2GSink(); +} + +void CWE190_Integer_Overflow__int_connect_socket_preinc_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_preinc_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_preinc_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_square_64b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_square_64b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_square_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int64_t * dataPtr = (int64_t *)dataVoidPtr; + /* dereference dataPtr into data */ + int64_t data = (*dataPtr); + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_square_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int64_t * dataPtr = (int64_t *)dataVoidPtr; + /* dereference dataPtr into data */ + int64_t data = (*dataPtr); + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_square_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int64_t * dataPtr = (int64_t *)dataVoidPtr; + /* dereference dataPtr into data */ + int64_t data = (*dataPtr); + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_square_52b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_52b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_52c_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_square_52b_badSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_square_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_52c_goodG2BSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_square_52b_goodG2BSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_square_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_52c_goodB2GSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_square_52b_goodB2GSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_square_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_max_add_22b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_add_22b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE190_Integer_Overflow__unsigned_int_max_add_22_badGlobal; + +void CWE190_Integer_Overflow__unsigned_int_max_add_22_badSink(unsigned int data) +{ + if(CWE190_Integer_Overflow__unsigned_int_max_add_22_badGlobal) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE190_Integer_Overflow__unsigned_int_max_add_22_goodB2G1Global; +extern int CWE190_Integer_Overflow__unsigned_int_max_add_22_goodB2G2Global; +extern int CWE190_Integer_Overflow__unsigned_int_max_add_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__unsigned_int_max_add_22_goodB2G1Sink(unsigned int data) +{ + if(CWE190_Integer_Overflow__unsigned_int_max_add_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__unsigned_int_max_add_22_goodB2G2Sink(unsigned int data) +{ + if(CWE190_Integer_Overflow__unsigned_int_max_add_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__unsigned_int_max_add_22_goodG2BSink(unsigned int data) +{ + if(CWE190_Integer_Overflow__unsigned_int_max_add_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_multiply_22b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_multiply_22b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_badGlobal; + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_badSink(unsigned int data) +{ + if(CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_badGlobal) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodB2G1Global; +extern int CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodB2G2Global; +extern int CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodB2G1Sink(unsigned int data) +{ + if(CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodB2G2Sink(unsigned int data) +{ + if(CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodB2G2Global) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodG2BSink(unsigned int data) +{ + if(CWE190_Integer_Overflow__unsigned_int_rand_multiply_22_goodG2BGlobal) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_preinc_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_preinc_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_13_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_preinc_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_preinc_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_square_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_square_08.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_square_08_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_square_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_square_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_square_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_preinc_66a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_preinc_66a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_rand_preinc_66b_badSink(char dataArray[]); + +void CWE190_Integer_Overflow__char_rand_preinc_66_bad() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + /* put data in array */ + dataArray[2] = data; + CWE190_Integer_Overflow__char_rand_preinc_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_rand_preinc_66b_goodG2BSink(char dataArray[]); + +static void goodG2B() +{ + char data; + char dataArray[5]; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + dataArray[2] = data; + CWE190_Integer_Overflow__char_rand_preinc_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_rand_preinc_66b_goodB2GSink(char dataArray[]); + +static void goodB2G() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + dataArray[2] = data; + CWE190_Integer_Overflow__char_rand_preinc_66b_goodB2GSink(dataArray); +} + +void CWE190_Integer_Overflow__char_rand_preinc_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_preinc_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_preinc_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_01.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_01.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_preinc_01_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__char_fscanf_preinc_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_preinc_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_preinc_63b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_preinc_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_rand_preinc_54a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_preinc_54a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_54b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_preinc_54_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE190_Integer_Overflow__int64_t_rand_preinc_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_54b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_rand_preinc_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_54b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE190_Integer_Overflow__int64_t_rand_preinc_54b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int64_t_rand_preinc_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_preinc_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_preinc_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_preinc_21.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_preinc_21.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_max_preinc_21_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__int_max_preinc_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_preinc_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_preinc_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_postinc_09.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_postinc_09.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_postinc_09_bad() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_postinc_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_postinc_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_postinc_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_53a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_53a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_fscanf_preinc_53b_badSink(char data); + +void CWE190_Integer_Overflow__char_fscanf_preinc_53_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE190_Integer_Overflow__char_fscanf_preinc_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_fscanf_preinc_53b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_fscanf_preinc_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_fscanf_preinc_53b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE190_Integer_Overflow__char_fscanf_preinc_53b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__char_fscanf_preinc_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_square_53c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_square_53c.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_max_square_53d_badSink(int data); + +void CWE190_Integer_Overflow__int_max_square_53c_badSink(int data) +{ + CWE190_Integer_Overflow__int_max_square_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_max_square_53d_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_max_square_53c_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_max_square_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_max_square_53d_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_max_square_53c_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_max_square_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_max_add_67a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_add_67a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE190_Integer_Overflow__unsigned_int_max_add_67_structType +{ + unsigned int structFirst; +} CWE190_Integer_Overflow__unsigned_int_max_add_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_max_add_67b_badSink(CWE190_Integer_Overflow__unsigned_int_max_add_67_structType myStruct); + +void CWE190_Integer_Overflow__unsigned_int_max_add_67_bad() +{ + unsigned int data; + CWE190_Integer_Overflow__unsigned_int_max_add_67_structType myStruct; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + myStruct.structFirst = data; + CWE190_Integer_Overflow__unsigned_int_max_add_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_max_add_67b_goodG2BSink(CWE190_Integer_Overflow__unsigned_int_max_add_67_structType myStruct); + +static void goodG2B() +{ + unsigned int data; + CWE190_Integer_Overflow__unsigned_int_max_add_67_structType myStruct; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + myStruct.structFirst = data; + CWE190_Integer_Overflow__unsigned_int_max_add_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_max_add_67b_goodB2GSink(CWE190_Integer_Overflow__unsigned_int_max_add_67_structType myStruct); + +static void goodB2G() +{ + unsigned int data; + CWE190_Integer_Overflow__unsigned_int_max_add_67_structType myStruct; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + myStruct.structFirst = data; + CWE190_Integer_Overflow__unsigned_int_max_add_67b_goodB2GSink(myStruct); +} + +void CWE190_Integer_Overflow__unsigned_int_max_add_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_add_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_add_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_square_14.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_square_14.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_square_14_bad() +{ + int64_t data; + data = 0LL; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_square_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_square_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_square_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_preinc_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_preinc_63a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_max_preinc_63b_badSink(short * dataPtr); + +void CWE190_Integer_Overflow__short_max_preinc_63_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + CWE190_Integer_Overflow__short_max_preinc_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_preinc_63b_goodG2BSink(short * data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__short_max_preinc_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_preinc_63b_goodB2GSink(short * data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + CWE190_Integer_Overflow__short_max_preinc_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__short_max_preinc_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_preinc_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_preinc_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_square_45.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_square_45.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +static char CWE190_Integer_Overflow__char_rand_square_45_badData; +static char CWE190_Integer_Overflow__char_rand_square_45_goodG2BData; +static char CWE190_Integer_Overflow__char_rand_square_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + char data = CWE190_Integer_Overflow__char_rand_square_45_badData; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +void CWE190_Integer_Overflow__char_rand_square_45_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE190_Integer_Overflow__char_rand_square_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char data = CWE190_Integer_Overflow__char_rand_square_45_goodG2BData; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_rand_square_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + char data = CWE190_Integer_Overflow__char_rand_square_45_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE190_Integer_Overflow__char_rand_square_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE190_Integer_Overflow__char_rand_square_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_square_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_square_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_preinc_17.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_preinc_17.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_preinc_17_bad() +{ + int i,j; + char data; + data = ' '; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + char data; + data = ' '; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + char data; + data = ' '; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_max_preinc_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_preinc_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_preinc_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_square_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_square_63a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_63b_badSink(unsigned int * dataPtr); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_63_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_63b_goodG2BSink(unsigned int * data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_fscanf_square_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_63b_goodB2GSink(unsigned int * data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_postinc_45.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_postinc_45.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static int CWE190_Integer_Overflow__int_max_postinc_45_badData; +static int CWE190_Integer_Overflow__int_max_postinc_45_goodG2BData; +static int CWE190_Integer_Overflow__int_max_postinc_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int data = CWE190_Integer_Overflow__int_max_postinc_45_badData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_max_postinc_45_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + CWE190_Integer_Overflow__int_max_postinc_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int data = CWE190_Integer_Overflow__int_max_postinc_45_goodG2BData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_max_postinc_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int data = CWE190_Integer_Overflow__int_max_postinc_45_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + CWE190_Integer_Overflow__int_max_postinc_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE190_Integer_Overflow__int_max_postinc_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_postinc_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_postinc_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_square_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_square_63a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_max_square_63b_badSink(char * dataPtr); + +void CWE190_Integer_Overflow__char_max_square_63_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + CWE190_Integer_Overflow__char_max_square_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_square_63b_goodG2BSink(char * data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_max_square_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_square_63b_goodB2GSink(char * data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + CWE190_Integer_Overflow__char_max_square_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__char_max_square_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_square_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_square_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_multiply_53a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_multiply_53a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_53b_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_53_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_53b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_rand_multiply_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_53b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_53b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_square_34.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_square_34.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +typedef union +{ + int unionFirst; + int unionSecond; +} CWE190_Integer_Overflow__int_fgets_square_34_unionType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_square_34_bad() +{ + int data; + CWE190_Integer_Overflow__int_fgets_square_34_unionType myUnion; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + CWE190_Integer_Overflow__int_fgets_square_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + CWE190_Integer_Overflow__int_fgets_square_34_unionType myUnion; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_square_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_square_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_square_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_square_14.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_square_14.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_square_14_bad() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_square_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_square_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_square_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_postinc_34.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_postinc_34.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +typedef union +{ + int unionFirst; + int unionSecond; +} CWE190_Integer_Overflow__int_rand_postinc_34_unionType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_postinc_34_bad() +{ + int data; + CWE190_Integer_Overflow__int_rand_postinc_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + CWE190_Integer_Overflow__int_rand_postinc_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + CWE190_Integer_Overflow__int_rand_postinc_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_rand_postinc_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_postinc_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_postinc_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_add_18.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_add_18.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_add_18_bad() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + goto sink; +sink: + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + goto sink; +sink: + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +void CWE190_Integer_Overflow__int64_t_rand_add_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_add_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_add_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_preinc_22b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_preinc_22b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_badGlobal; + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_badSink(int64_t data) +{ + if(CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_badGlobal) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodB2G1Global; +extern int CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodB2G2Global; +extern int CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodB2G1Sink(int64_t data) +{ + if(CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodB2G2Sink(int64_t data) +{ + if(CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodG2BSink(int64_t data) +{ + if(CWE190_Integer_Overflow__int64_t_fscanf_preinc_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_fscanf_postinc_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_postinc_54d.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_fscanf_postinc_54e_badSink(char data); + +void CWE190_Integer_Overflow__char_fscanf_postinc_54d_badSink(char data) +{ + CWE190_Integer_Overflow__char_fscanf_postinc_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_fscanf_postinc_54e_goodG2BSink(char data); + +void CWE190_Integer_Overflow__char_fscanf_postinc_54d_goodG2BSink(char data) +{ + CWE190_Integer_Overflow__char_fscanf_postinc_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_fscanf_postinc_54e_goodB2GSink(char data); + +void CWE190_Integer_Overflow__char_fscanf_postinc_54d_goodB2GSink(char data) +{ + CWE190_Integer_Overflow__char_fscanf_postinc_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_connect_socket_multiply_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_multiply_63b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_multiply_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_multiply_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_multiply_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_listen_socket_square_65b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_square_65b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_square_65b_badSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_65b_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_65b_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_add_65b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_65b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_add_65b_badSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_add_65b_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_add_65b_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_max_preinc_53c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_preinc_53c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_max_preinc_53d_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_preinc_53c_badSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_preinc_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_preinc_53d_goodG2BSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_preinc_53c_goodG2BSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_preinc_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_preinc_53d_goodB2GSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_preinc_53c_goodB2GSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_preinc_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_max_preinc_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_preinc_63b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_preinc_63b_badSink(short * dataPtr) +{ + short data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_preinc_63b_goodG2BSink(short * dataPtr) +{ + short data = *dataPtr; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_preinc_63b_goodB2GSink(short * dataPtr) +{ + short data = *dataPtr; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + ++data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_listen_socket_preinc_64a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_preinc_64a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_listen_socket_preinc_64b_badSink(void * dataVoidPtr); + +void CWE190_Integer_Overflow__int_listen_socket_preinc_64_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_listen_socket_preinc_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_preinc_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_listen_socket_preinc_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_preinc_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_listen_socket_preinc_64b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int_listen_socket_preinc_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_preinc_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_preinc_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_postinc_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_postinc_65a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_65b_badSink(int data); + +void CWE190_Integer_Overflow__int_connect_socket_postinc_65_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_connect_socket_postinc_65b_badSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_65b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_connect_socket_postinc_65b_goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_65b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_connect_socket_postinc_65b_goodB2GSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + funcPtr(data); +} + +void CWE190_Integer_Overflow__int_connect_socket_postinc_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_postinc_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_postinc_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_square_01.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_square_01.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_01_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_add_34.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_34.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +typedef union +{ + unsigned int unionFirst; + unsigned int unionSecond; +} CWE190_Integer_Overflow__unsigned_int_rand_add_34_unionType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_add_34_bad() +{ + unsigned int data; + CWE190_Integer_Overflow__unsigned_int_rand_add_34_unionType myUnion; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + myUnion.unionFirst = data; + { + unsigned int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + CWE190_Integer_Overflow__unsigned_int_rand_add_34_unionType myUnion; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + myUnion.unionFirst = data; + { + unsigned int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + CWE190_Integer_Overflow__unsigned_int_rand_add_34_unionType myUnion; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + myUnion.unionFirst = data; + { + unsigned int data = myUnion.unionSecond; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_add_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_preinc_54a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_preinc_54a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_max_preinc_54b_badSink(char data); + +void CWE190_Integer_Overflow__char_max_preinc_54_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + CWE190_Integer_Overflow__char_max_preinc_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_preinc_54b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_max_preinc_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_preinc_54b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + CWE190_Integer_Overflow__char_max_preinc_54b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__char_max_preinc_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_preinc_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_preinc_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_postinc_07.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_postinc_07.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-07.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + any other value so a tool should be able to identify that reads of + this will always give its initialized value. */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_postinc_07_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticFive==5 to staticFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(staticFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_max_postinc_07_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_postinc_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_postinc_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_preinc_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_preinc_52c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_52c_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_52c_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_52c_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_max_square_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_square_65a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_max_square_65b_badSink(short data); + +void CWE190_Integer_Overflow__short_max_square_65_bad() +{ + short data; + /* define a function pointer */ + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_square_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_square_65b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_square_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_square_65b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_square_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + funcPtr(data); +} + +void CWE190_Integer_Overflow__short_max_square_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_square_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_square_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_postinc_17.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_postinc_17.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_postinc_17_bad() +{ + int i,j; + int64_t data; + data = 0LL; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int64_t data; + data = 0LL; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int64_t data; + data = 0LL; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_postinc_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_postinc_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_postinc_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_multiply_03.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_multiply_03.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_multiply_03_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_multiply_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_multiply_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_multiply_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_square_02.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_square_02.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_square_02_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_max_square_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_square_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_square_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_multiply_41.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_multiply_41.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_41_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } +} + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + goodB2GSink(data); +} + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_square_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_54c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_54d_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_square_54c_badSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_square_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_54d_goodG2BSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_square_54c_goodG2BSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_square_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_54d_goodB2GSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_square_54c_goodB2GSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_rand_square_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_rand_postinc_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_postinc_68b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern int64_t CWE190_Integer_Overflow__int64_t_rand_postinc_68_badData; +extern int64_t CWE190_Integer_Overflow__int64_t_rand_postinc_68_goodG2BData; +extern int64_t CWE190_Integer_Overflow__int64_t_rand_postinc_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_postinc_68b_badSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_rand_postinc_68_badData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_rand_postinc_68b_goodG2BSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_rand_postinc_68_goodG2BData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_rand_postinc_68b_goodB2GSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_rand_postinc_68_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_square_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_square_52c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_square_52c_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_52c_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_52c_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_listen_socket_add_14.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_add_14.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_add_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_add_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_add_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_add_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_square_09.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_square_09.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_square_09_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_connect_socket_square_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_square_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_square_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_add_09.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_add_09.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_add_09_bad() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_add_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_add_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_add_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_preinc_65b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_preinc_65b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_preinc_65b_badSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_preinc_65b_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_preinc_65b_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_connect_socket_postinc_67b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_postinc_67b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef struct _CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType +{ + int structFirst; +} CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_postinc_67b_badSink(CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct) +{ + int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_67b_goodG2BSink(CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct) +{ + int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_67b_goodB2GSink(CWE190_Integer_Overflow__int_connect_socket_postinc_67_structType myStruct) +{ + int data = myStruct.structFirst; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_max_multiply_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_multiply_54d.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_max_multiply_54e_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_multiply_54d_badSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_multiply_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_multiply_54e_goodG2BSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_multiply_54d_goodG2BSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_multiply_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_multiply_54e_goodB2GSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_multiply_54d_goodB2GSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_multiply_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_fscanf_add_53d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_add_53d.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_53d_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_53d_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_53d_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_rand_multiply_41.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_multiply_41.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +void CWE190_Integer_Overflow__char_rand_multiply_41_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + goodB2GSink(data); +} + +void CWE190_Integer_Overflow__char_rand_multiply_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_multiply_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_multiply_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_postinc_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_postinc_08.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_08_bad() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_square_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_square_52c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_square_52c_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_square_52c_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_square_52c_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_add_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_68b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern unsigned int CWE190_Integer_Overflow__unsigned_int_rand_add_68_badData; +extern unsigned int CWE190_Integer_Overflow__unsigned_int_rand_add_68_goodG2BData; +extern unsigned int CWE190_Integer_Overflow__unsigned_int_rand_add_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_add_68b_badSink() +{ + unsigned int data = CWE190_Integer_Overflow__unsigned_int_rand_add_68_badData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_68b_goodG2BSink() +{ + unsigned int data = CWE190_Integer_Overflow__unsigned_int_rand_add_68_goodG2BData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_68b_goodB2GSink() +{ + unsigned int data = CWE190_Integer_Overflow__unsigned_int_rand_add_68_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_connect_socket_postinc_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_postinc_52c.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_postinc_52c_badSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_52c_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_postinc_52c_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_max_preinc_11.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_preinc_11.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_11_bad() +{ + unsigned int data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_preinc_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_preinc_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_multiply_17.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_multiply_17.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_multiply_17_bad() +{ + int i,j; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + for(j = 0; j < 1; j++) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + for(k = 0; k < 1; k++) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int data; + /* Initialize data */ + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + for(j = 0; j < 1; j++) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_max_multiply_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_multiply_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_multiply_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_multiply_53a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_multiply_53a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fscanf_multiply_53b_badSink(int data); + +void CWE190_Integer_Overflow__int_fscanf_multiply_53_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_multiply_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_multiply_53b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fscanf_multiply_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_multiply_53b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_multiply_53b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int_fscanf_multiply_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_preinc_66b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_preinc_66b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_preinc_66b_badSink(int dataArray[]) +{ + /* copy data out of dataArray */ + int data = dataArray[2]; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fgets_preinc_66b_goodG2BSink(int dataArray[]) +{ + int data = dataArray[2]; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fgets_preinc_66b_goodB2GSink(int dataArray[]) +{ + int data = dataArray[2]; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_max_square_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_square_54c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_max_square_54d_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_square_54c_badSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_square_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_square_54d_goodG2BSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_square_54c_goodG2BSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_square_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_square_54d_goodB2GSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_square_54c_goodB2GSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_square_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_multiply_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_multiply_63a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fscanf_multiply_63b_badSink(int * dataPtr); + +void CWE190_Integer_Overflow__int_fscanf_multiply_63_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_multiply_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_multiply_63b_goodG2BSink(int * data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fscanf_multiply_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_multiply_63b_goodB2GSink(int * data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_multiply_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int_fscanf_multiply_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_multiply_02.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_multiply_02.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_multiply_02_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_multiply_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_multiply_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_multiply_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_preinc_54e.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_preinc_54e.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_54e_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_54e_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_54e_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_rand_postinc_41.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_postinc_41.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(short data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__short_rand_postinc_41_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + goodB2GSink(data); +} + +void CWE190_Integer_Overflow__short_rand_postinc_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_postinc_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_postinc_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_multiply_51b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_multiply_51b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_multiply_51b_badSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_multiply_51b_goodG2BSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_multiply_51b_goodB2GSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_preinc_07.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_preinc_07.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-07.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + any other value so a tool should be able to identify that reads of + this will always give its initialized value. */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_preinc_07_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticFive==5 to staticFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(staticFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_preinc_07_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_preinc_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_preinc_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_66b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_66b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_preinc_66b_badSink(char dataArray[]) +{ + /* copy data out of dataArray */ + char data = dataArray[2]; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_fscanf_preinc_66b_goodG2BSink(char dataArray[]) +{ + char data = dataArray[2]; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_fscanf_preinc_66b_goodB2GSink(char dataArray[]) +{ + char data = dataArray[2]; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_rand_preinc_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_preinc_54d.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_54e_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_preinc_54d_badSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_rand_preinc_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_54e_goodG2BSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_preinc_54d_goodG2BSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_rand_preinc_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_54e_goodB2GSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_preinc_54d_goodB2GSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_rand_preinc_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_multiply_66a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_multiply_66a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_66b_badSink(int64_t dataArray[]); + +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_66_bad() +{ + int64_t data; + int64_t dataArray[5]; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%lld"", &data); + /* put data in array */ + dataArray[2] = data; + CWE190_Integer_Overflow__int64_t_fscanf_multiply_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_66b_goodG2BSink(int64_t dataArray[]); + +static void goodG2B() +{ + int64_t data; + int64_t dataArray[5]; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + dataArray[2] = data; + CWE190_Integer_Overflow__int64_t_fscanf_multiply_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_66b_goodB2GSink(int64_t dataArray[]); + +static void goodB2G() +{ + int64_t data; + int64_t dataArray[5]; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%lld"", &data); + dataArray[2] = data; + CWE190_Integer_Overflow__int64_t_fscanf_multiply_66b_goodB2GSink(dataArray); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_multiply_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_multiply_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_multiply_54b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_multiply_54b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_listen_socket_multiply_54c_badSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_multiply_54b_badSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_multiply_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_multiply_54c_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_multiply_54b_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_multiply_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_multiply_54c_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_multiply_54b_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_multiply_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_max_preinc_16.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_preinc_16.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_preinc_16_bad() +{ + short data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + short result = data; + printIntLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + short data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + ++data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + short data; + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + short result = data; + printIntLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__short_max_preinc_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_preinc_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_preinc_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_32.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_32.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_32_bad() +{ + unsigned int data; + unsigned int *dataPtr1 = &data; + unsigned int *dataPtr2 = &data; + data = 0; + { + unsigned int data = *dataPtr1; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + *dataPtr1 = data; + } + { + unsigned int data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + unsigned int *dataPtr1 = &data; + unsigned int *dataPtr2 = &data; + data = 0; + { + unsigned int data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + unsigned int data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + unsigned int *dataPtr1 = &data; + unsigned int *dataPtr2 = &data; + data = 0; + { + unsigned int data = *dataPtr1; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + *dataPtr1 = data; + } + { + unsigned int data = *dataPtr2; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_preinc_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_multiply_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_multiply_51a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_51b_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_51_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_51b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_rand_multiply_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_51b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_add_14.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_add_14.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_add_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_connect_socket_add_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_add_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_add_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_add_64b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_add_64b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_add_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_add_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_add_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_postinc_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_postinc_68b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern int CWE190_Integer_Overflow__int_fscanf_postinc_68_badData; +extern int CWE190_Integer_Overflow__int_fscanf_postinc_68_goodG2BData; +extern int CWE190_Integer_Overflow__int_fscanf_postinc_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_postinc_68b_badSink() +{ + int data = CWE190_Integer_Overflow__int_fscanf_postinc_68_badData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_68b_goodG2BSink() +{ + int data = CWE190_Integer_Overflow__int_fscanf_postinc_68_goodG2BData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_68b_goodB2GSink() +{ + int data = CWE190_Integer_Overflow__int_fscanf_postinc_68_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_connect_socket_preinc_66b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_preinc_66b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_preinc_66b_badSink(int dataArray[]) +{ + /* copy data out of dataArray */ + int data = dataArray[2]; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_66b_goodG2BSink(int dataArray[]) +{ + int data = dataArray[2]; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_preinc_66b_goodB2GSink(int dataArray[]) +{ + int data = dataArray[2]; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fgets_postinc_52b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_postinc_52b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fgets_postinc_52c_badSink(int data); + +void CWE190_Integer_Overflow__int_fgets_postinc_52b_badSink(int data) +{ + CWE190_Integer_Overflow__int_fgets_postinc_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fgets_postinc_52c_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_fgets_postinc_52b_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_fgets_postinc_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fgets_postinc_52c_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_fgets_postinc_52b_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_fgets_postinc_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_add_45.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_45.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static int CWE190_Integer_Overflow__int_fscanf_add_45_badData; +static int CWE190_Integer_Overflow__int_fscanf_add_45_goodG2BData; +static int CWE190_Integer_Overflow__int_fscanf_add_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int data = CWE190_Integer_Overflow__int_fscanf_add_45_badData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_fscanf_add_45_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_add_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int data = CWE190_Integer_Overflow__int_fscanf_add_45_goodG2BData; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fscanf_add_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int data = CWE190_Integer_Overflow__int_fscanf_add_45_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_add_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE190_Integer_Overflow__int_fscanf_add_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_add_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_add_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_square_14.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_square_14.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_square_14_bad() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_max_square_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_square_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_square_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_add_44.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_add_44.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_max_add_44_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = badSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = goodB2GSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + funcPtr(data); +} + +void CWE190_Integer_Overflow__int_max_add_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_add_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_add_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_preinc_04.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_preinc_04.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_04_bad() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(STATIC_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_preinc_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_preinc_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_preinc_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_multiply_67b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_multiply_67b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE190_Integer_Overflow__unsigned_int_rand_multiply_67_structType +{ + unsigned int structFirst; +} CWE190_Integer_Overflow__unsigned_int_rand_multiply_67_structType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_67b_badSink(CWE190_Integer_Overflow__unsigned_int_rand_multiply_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_67b_goodG2BSink(CWE190_Integer_Overflow__unsigned_int_rand_multiply_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_67b_goodB2GSink(CWE190_Integer_Overflow__unsigned_int_rand_multiply_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_fscanf_multiply_53a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_multiply_53a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_fscanf_multiply_53b_badSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_multiply_53_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_multiply_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_multiply_53b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__short_fscanf_multiply_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_multiply_53b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_multiply_53b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__short_fscanf_multiply_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_multiply_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_multiply_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_preinc_12.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_preinc_12.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_preinc_12_bad() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + else + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_preinc_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_preinc_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_preinc_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_max_postinc_66a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_postinc_66a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_max_postinc_66b_badSink(unsigned int dataArray[]); + +void CWE190_Integer_Overflow__unsigned_int_max_postinc_66_bad() +{ + unsigned int data; + unsigned int dataArray[5]; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + /* put data in array */ + dataArray[2] = data; + CWE190_Integer_Overflow__unsigned_int_max_postinc_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_max_postinc_66b_goodG2BSink(unsigned int dataArray[]); + +static void goodG2B() +{ + unsigned int data; + unsigned int dataArray[5]; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + dataArray[2] = data; + CWE190_Integer_Overflow__unsigned_int_max_postinc_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_max_postinc_66b_goodB2GSink(unsigned int dataArray[]); + +static void goodB2G() +{ + unsigned int data; + unsigned int dataArray[5]; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + dataArray[2] = data; + CWE190_Integer_Overflow__unsigned_int_max_postinc_66b_goodB2GSink(dataArray); +} + +void CWE190_Integer_Overflow__unsigned_int_max_postinc_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_postinc_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_postinc_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_square_63a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_square_63a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_63b_badSink(int64_t * dataPtr); + +void CWE190_Integer_Overflow__int64_t_fscanf_square_63_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_square_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_63b_goodG2BSink(int64_t * data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_fscanf_square_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_square_63b_goodB2GSink(int64_t * data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_square_63b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_square_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_square_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_square_31.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_square_31.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_square_31_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + { + char dataCopy = data; + char data = dataCopy; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + { + char dataCopy = data; + char data = dataCopy; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + { + char dataCopy = data; + char data = dataCopy; + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_square_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_square_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_square_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_preinc_32.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_preinc_32.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_preinc_32_bad() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_preinc_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_preinc_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_preinc_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_04.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_04.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_preinc_04_bad() +{ + char data; + data = ' '; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + char data; + data = ' '; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(STATIC_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char data; + data = ' '; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_preinc_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_square_52a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_square_52a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_rand_square_52b_badSink(short data); + +void CWE190_Integer_Overflow__short_rand_square_52_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE190_Integer_Overflow__short_rand_square_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_rand_square_52b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__short_rand_square_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_rand_square_52b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE190_Integer_Overflow__short_rand_square_52b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__short_rand_square_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_square_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_square_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_52c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_52c_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_52c_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_postinc_52c_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_max_postinc_32.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_postinc_32.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_postinc_32_bad() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int64_t_max_postinc_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_postinc_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_postinc_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_multiply_61a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_multiply_61a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE190_Integer_Overflow__int_listen_socket_multiply_61b_badSource(int data); + +void CWE190_Integer_Overflow__int_listen_socket_multiply_61_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_listen_socket_multiply_61b_badSource(data); + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE190_Integer_Overflow__int_listen_socket_multiply_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_listen_socket_multiply_61b_goodG2BSource(data); + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE190_Integer_Overflow__int_listen_socket_multiply_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_listen_socket_multiply_61b_goodB2GSource(data); + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_multiply_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_multiply_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_multiply_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_add_22a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_22a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-22a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +int CWE190_Integer_Overflow__int_fscanf_add_22_badGlobal = 0; + +void CWE190_Integer_Overflow__int_fscanf_add_22_badSink(int data); + +void CWE190_Integer_Overflow__int_fscanf_add_22_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_add_22_badGlobal = 1; /* true */ + CWE190_Integer_Overflow__int_fscanf_add_22_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +int CWE190_Integer_Overflow__int_fscanf_add_22_goodB2G1Global = 0; +int CWE190_Integer_Overflow__int_fscanf_add_22_goodB2G2Global = 0; +int CWE190_Integer_Overflow__int_fscanf_add_22_goodG2BGlobal = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__int_fscanf_add_22_goodB2G1Sink(int data); + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_add_22_goodB2G1Global = 0; /* false */ + CWE190_Integer_Overflow__int_fscanf_add_22_goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__int_fscanf_add_22_goodB2G2Sink(int data); + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_add_22_goodB2G2Global = 1; /* true */ + CWE190_Integer_Overflow__int_fscanf_add_22_goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__int_fscanf_add_22_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fscanf_add_22_goodG2BGlobal = 1; /* true */ + CWE190_Integer_Overflow__int_fscanf_add_22_goodG2BSink(data); +} + +void CWE190_Integer_Overflow__int_fscanf_add_22_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_add_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_add_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_postinc_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_postinc_51a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_fscanf_postinc_51b_badSink(char data); + +void CWE190_Integer_Overflow__char_fscanf_postinc_51_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE190_Integer_Overflow__char_fscanf_postinc_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_fscanf_postinc_51b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__char_fscanf_postinc_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_fscanf_postinc_51b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE190_Integer_Overflow__char_fscanf_postinc_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__char_fscanf_postinc_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_postinc_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_postinc_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_preinc_52a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_preinc_52a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_fscanf_preinc_52b_badSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_preinc_52_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_preinc_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_preinc_52b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__short_fscanf_preinc_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_preinc_52b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_preinc_52b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__short_fscanf_preinc_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_preinc_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_preinc_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_add_16.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_add_16.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_add_16_bad() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__int_fgets_add_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_add_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_add_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_preinc_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_preinc_52c.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_preinc_52c_badSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fgets_preinc_52c_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fgets_preinc_52c_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_max_postinc_67b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_postinc_67b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE190_Integer_Overflow__short_max_postinc_67_structType +{ + short structFirst; +} CWE190_Integer_Overflow__short_max_postinc_67_structType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_postinc_67b_badSink(CWE190_Integer_Overflow__short_max_postinc_67_structType myStruct) +{ + short data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_postinc_67b_goodG2BSink(CWE190_Integer_Overflow__short_max_postinc_67_structType myStruct) +{ + short data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_postinc_67b_goodB2GSink(CWE190_Integer_Overflow__short_max_postinc_67_structType myStruct) +{ + short data = myStruct.structFirst; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_04.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_04.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_04_bad() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(STATIC_CONST_TRUE) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(STATIC_CONST_TRUE) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_multiply_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_preinc_52b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_preinc_52b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_max_preinc_52c_badSink(int data); + +void CWE190_Integer_Overflow__int_max_preinc_52b_badSink(int data) +{ + CWE190_Integer_Overflow__int_max_preinc_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_max_preinc_52c_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_max_preinc_52b_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_max_preinc_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_max_preinc_52c_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_max_preinc_52b_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_max_preinc_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_rand_add_03.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_add_03.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_add_03_bad() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_add_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_add_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_add_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_square_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_square_52c.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_square_52c_badSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_max_square_52c_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_max_square_52c_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_fscanf_add_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_add_65a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_fscanf_add_65b_badSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_add_65_bad() +{ + short data; + /* define a function pointer */ + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_fscanf_add_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_add_65b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_fscanf_add_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_add_65b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_fscanf_add_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + funcPtr(data); +} + +void CWE190_Integer_Overflow__short_fscanf_add_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_add_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_add_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_multiply_16.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_multiply_16.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_multiply_16_bad() +{ + int64_t data; + data = 0LL; + while(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + break; + } + while(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + while(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + break; + } + while(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + } + while(1) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__int64_t_max_multiply_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_multiply_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_multiply_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_square_21.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_square_21.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(short data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: if (data*data) > SHRT_MAX, this will overflow */ + short result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__short_fscanf_square_21_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(short data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)SHRT_MAX)) + { + short result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(short data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)SHRT_MAX)) + { + short result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(short data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: if (data*data) > SHRT_MAX, this will overflow */ + short result = data * data; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__short_fscanf_square_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_square_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_square_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_add_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_add_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_13_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_add_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_add_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_add_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_add_61b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +int CWE190_Integer_Overflow__int_fgets_add_61b_badSource(int data) +{ + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +int CWE190_Integer_Overflow__int_fgets_add_61b_goodG2BSource(int data) +{ + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +int CWE190_Integer_Overflow__int_fgets_add_61b_goodB2GSource(int data) +{ + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_rand_multiply_51a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_multiply_51a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_rand_multiply_51b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_multiply_51_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE190_Integer_Overflow__int64_t_rand_multiply_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_rand_multiply_51b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_rand_multiply_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_rand_multiply_51b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE190_Integer_Overflow__int64_t_rand_multiply_51b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int64_t_rand_multiply_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_multiply_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_multiply_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_multiply_51b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_multiply_51b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_multiply_51b_badSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_multiply_51b_goodG2BSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_multiply_51b_goodB2GSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (SHRT_MAX/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_connect_socket_multiply_54e.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_multiply_54e.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_multiply_54e_badSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_connect_socket_multiply_54e_goodG2BSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_connect_socket_multiply_54e_goodB2GSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_max_multiply_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_multiply_68b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern short CWE190_Integer_Overflow__short_max_multiply_68_badData; +extern short CWE190_Integer_Overflow__short_max_multiply_68_goodG2BData; +extern short CWE190_Integer_Overflow__short_max_multiply_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_multiply_68b_badSink() +{ + short data = CWE190_Integer_Overflow__short_max_multiply_68_badData; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_multiply_68b_goodG2BSink() +{ + short data = CWE190_Integer_Overflow__short_max_multiply_68_goodG2BData; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_multiply_68b_goodB2GSink() +{ + short data = CWE190_Integer_Overflow__short_max_multiply_68_goodB2GData; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (SHRT_MAX/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_preinc_12.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_preinc_12.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_12_bad() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + else + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_08.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_preinc_08_bad() +{ + char data; + data = ' '; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + char data; + data = ' '; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char data; + data = ' '; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_preinc_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_add_03.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_add_03.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_add_03_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_add_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_add_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_add_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_add_12.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_12.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_add_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + else + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_add_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_add_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_add_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_postinc_53d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_postinc_53d.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_53d_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_53d_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_53d_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_listen_socket_postinc_03.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_postinc_03.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_postinc_03_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_postinc_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_postinc_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_postinc_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_multiply_15.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_multiply_15.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_rand_multiply_15_bad() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (SHRT_MAX/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (SHRT_MAX/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + short data; + data = 0; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + } + switch(7) + { + case 7: + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE190_Integer_Overflow__short_rand_multiply_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_multiply_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_multiply_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_square_11.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_square_11.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_square_11_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_connect_socket_square_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_square_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_square_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_square_64b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_square_64b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_square_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_square_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_square_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_postinc_05.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_postinc_05.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_05_bad() +{ + unsigned int data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(staticTrue) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_postinc_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_postinc_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_add_03.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_add_03.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_add_03_bad() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_max_add_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_add_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_add_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_postinc_66a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_postinc_66a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fscanf_postinc_66b_badSink(int dataArray[]); + +void CWE190_Integer_Overflow__int_fscanf_postinc_66_bad() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + /* put data in array */ + dataArray[2] = data; + CWE190_Integer_Overflow__int_fscanf_postinc_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_66b_goodG2BSink(int dataArray[]); + +static void goodG2B() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + dataArray[2] = data; + CWE190_Integer_Overflow__int_fscanf_postinc_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_66b_goodB2GSink(int dataArray[]); + +static void goodB2G() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + dataArray[2] = data; + CWE190_Integer_Overflow__int_fscanf_postinc_66b_goodB2GSink(dataArray); +} + +void CWE190_Integer_Overflow__int_fscanf_postinc_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_preinc_14.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_preinc_14.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_preinc_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_max_preinc_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_preinc_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_preinc_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_postinc_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_postinc_54d.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_rand_postinc_54e_badSink(int data); + +void CWE190_Integer_Overflow__int_rand_postinc_54d_badSink(int data) +{ + CWE190_Integer_Overflow__int_rand_postinc_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_postinc_54e_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_rand_postinc_54d_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_rand_postinc_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_postinc_54e_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_rand_postinc_54d_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_rand_postinc_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_max_multiply_17.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_multiply_17.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_max_multiply_17_bad() +{ + int i,j; + unsigned int data; + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + for(j = 0; j < 1; j++) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + unsigned int data; + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + for(k = 0; k < 1; k++) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + unsigned int data; + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + for(j = 0; j < 1; j++) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_max_multiply_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_multiply_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_multiply_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_postinc_05.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_postinc_05.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_postinc_05_bad() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(staticTrue) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + short data; + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__short_max_postinc_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_postinc_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_postinc_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_add_41.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_add_41.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(short data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__short_rand_add_41_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } +} + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + short result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + goodB2GSink(data); +} + +void CWE190_Integer_Overflow__short_rand_add_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_add_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_add_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_multiply_31.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_multiply_31.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_multiply_31_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + int dataCopy = data; + int data = dataCopy; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + { + int dataCopy = data; + int data = dataCopy; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + int dataCopy = data; + int data = dataCopy; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_multiply_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_multiply_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_multiply_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_add_17.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_add_17.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_add_17_bad() +{ + int i,j; + char data; + data = ' '; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + char data; + data = ' '; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + char data; + data = ' '; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_max_add_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_add_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_add_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_preinc_45.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_preinc_45.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include +#include ""std_testcase.h"" + +static int64_t CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_badData; +static int64_t CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_goodG2BData; +static int64_t CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_badData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_goodG2BData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int64_t data = CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_add_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_add_61b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +int64_t CWE190_Integer_Overflow__int64_t_rand_add_61b_badSource(int64_t data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +int64_t CWE190_Integer_Overflow__int64_t_rand_add_61b_goodG2BSource(int64_t data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +int64_t CWE190_Integer_Overflow__int64_t_rand_add_61b_goodB2GSource(int64_t data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_rand_add_05.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_add_05.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_add_05_bad() +{ + char data; + data = ' '; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + char data; + data = ' '; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticTrue) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + char data; + data = ' '; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_rand_add_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_add_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_add_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_preinc_01.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_preinc_01.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_preinc_01_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__int_max_preinc_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_preinc_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_preinc_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_add_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_add_54d.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_add_54e_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_add_54d_badSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_fscanf_add_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_add_54e_goodG2BSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_add_54d_goodG2BSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_fscanf_add_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_add_54e_goodB2GSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_add_54d_goodB2GSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_fscanf_add_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_listen_socket_add_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_add_54c.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_listen_socket_add_54d_badSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_add_54c_badSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_add_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_add_54d_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_add_54c_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_add_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_add_54d_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_add_54c_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_add_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_max_add_61a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_add_61a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +char CWE190_Integer_Overflow__char_max_add_61b_badSource(char data); + +void CWE190_Integer_Overflow__char_max_add_61_bad() +{ + char data; + data = ' '; + data = CWE190_Integer_Overflow__char_max_add_61b_badSource(data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +char CWE190_Integer_Overflow__char_max_add_61b_goodG2BSource(char data); + +static void goodG2B() +{ + char data; + data = ' '; + data = CWE190_Integer_Overflow__char_max_add_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +char CWE190_Integer_Overflow__char_max_add_61b_goodB2GSource(char data); + +static void goodB2G() +{ + char data; + data = ' '; + data = CWE190_Integer_Overflow__char_max_add_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__char_max_add_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_add_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_add_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_square_21.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_21.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(unsigned int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_square_21_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(unsigned int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(unsigned int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(unsigned int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__unsigned_int_rand_square_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_add_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_add_65a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_max_add_65b_badSink(short data); + +void CWE190_Integer_Overflow__short_max_add_65_bad() +{ + short data; + /* define a function pointer */ + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_add_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_add_65b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_add_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_add_65b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_max_add_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + funcPtr(data); +} + +void CWE190_Integer_Overflow__short_max_add_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_add_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_add_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_add_63b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_63b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_add_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_add_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_add_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fgets_preinc_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_preinc_65a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fgets_preinc_65b_badSink(int data); + +void CWE190_Integer_Overflow__int_fgets_preinc_65_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_fgets_preinc_65b_badSink; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fgets_preinc_65b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_fgets_preinc_65b_goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fgets_preinc_65b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = CWE190_Integer_Overflow__int_fgets_preinc_65b_goodB2GSink; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + funcPtr(data); +} + +void CWE190_Integer_Overflow__int_fgets_preinc_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_preinc_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_preinc_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_postinc_03.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_postinc_03.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_postinc_03_bad() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_max_postinc_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_postinc_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_postinc_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_add_01.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_add_01.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_add_01_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__char_fscanf_add_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_add_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_add_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_square_64b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_square_64b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_fscanf_square_18.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_square_18.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_18_bad() +{ + unsigned int data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + goto sink; +sink: + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + unsigned int data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + goto sink; +sink: + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + unsigned int data; + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goto sink; +sink: + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_fscanf_square_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_postinc_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_postinc_61b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +int CWE190_Integer_Overflow__int_fscanf_postinc_61b_badSource(int data) +{ + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +int CWE190_Integer_Overflow__int_fscanf_postinc_61b_goodG2BSource(int data) +{ + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +int CWE190_Integer_Overflow__int_fscanf_postinc_61b_goodB2GSource(int data) +{ + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_multiply_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_multiply_54d.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fscanf_multiply_54e_badSink(int data); + +void CWE190_Integer_Overflow__int_fscanf_multiply_54d_badSink(int data) +{ + CWE190_Integer_Overflow__int_fscanf_multiply_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_multiply_54e_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_fscanf_multiply_54d_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_fscanf_multiply_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_multiply_54e_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_fscanf_multiply_54d_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_fscanf_multiply_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_preinc_54a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_preinc_54a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_54b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_54_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_54b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_fscanf_preinc_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_54b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_54b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_square_54a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_square_54a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_max_square_54b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_square_54_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + CWE190_Integer_Overflow__int64_t_max_square_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_square_54b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_max_square_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_square_54b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + CWE190_Integer_Overflow__int64_t_max_square_54b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int64_t_max_square_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_square_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_square_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_add_65b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_65b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_add_65b_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_65b_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_65b_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_add_31.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_31.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_add_31_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + { + int dataCopy = data; + int data = dataCopy; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + { + int dataCopy = data; + int data = dataCopy; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + { + int dataCopy = data; + int data = dataCopy; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_add_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_add_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_add_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_preinc_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_preinc_13.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_preinc_13_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_preinc_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_preinc_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_preinc_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_square_09.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_square_09.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_square_09_bad() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_square_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_square_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_square_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_preinc_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_preinc_08.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_preinc_08_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_preinc_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_preinc_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_preinc_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_multiply_05.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_multiply_05.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_multiply_05_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(staticTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(staticTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(staticTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_multiply_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_multiply_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_multiply_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_add_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_add_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_add_13_bad() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_add_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_add_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_add_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_multiply_10.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_multiply_10.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_multiply_10_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_max_multiply_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_multiply_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_multiply_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_multiply_03.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_multiply_03.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_03_bad() +{ + unsigned int data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_postinc_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_postinc_65a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_rand_postinc_65b_badSink(short data); + +void CWE190_Integer_Overflow__short_rand_postinc_65_bad() +{ + short data; + /* define a function pointer */ + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_rand_postinc_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_rand_postinc_65b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_rand_postinc_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_rand_postinc_65b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + void (*funcPtr) (short) = CWE190_Integer_Overflow__short_rand_postinc_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + funcPtr(data); +} + +void CWE190_Integer_Overflow__short_rand_postinc_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_postinc_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_postinc_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_max_postinc_21.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_postinc_21.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(unsigned int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_max_postinc_21_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(unsigned int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(unsigned int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(unsigned int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__unsigned_int_max_postinc_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_postinc_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_postinc_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_add_14.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_14.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_add_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_add_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_add_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_add_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_postinc_66a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_postinc_66a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_max_postinc_66b_badSink(char dataArray[]); + +void CWE190_Integer_Overflow__char_max_postinc_66_bad() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + /* put data in array */ + dataArray[2] = data; + CWE190_Integer_Overflow__char_max_postinc_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_max_postinc_66b_goodG2BSink(char dataArray[]); + +static void goodG2B() +{ + char data; + char dataArray[5]; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + dataArray[2] = data; + CWE190_Integer_Overflow__char_max_postinc_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_max_postinc_66b_goodB2GSink(char dataArray[]); + +static void goodB2G() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + dataArray[2] = data; + CWE190_Integer_Overflow__char_max_postinc_66b_goodB2GSink(dataArray); +} + +void CWE190_Integer_Overflow__char_max_postinc_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_postinc_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_postinc_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_preinc_53c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_preinc_53c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_rand_preinc_53d_badSink(short data); + +void CWE190_Integer_Overflow__short_rand_preinc_53c_badSink(short data) +{ + CWE190_Integer_Overflow__short_rand_preinc_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_rand_preinc_53d_goodG2BSink(short data); + +void CWE190_Integer_Overflow__short_rand_preinc_53c_goodG2BSink(short data) +{ + CWE190_Integer_Overflow__short_rand_preinc_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_rand_preinc_53d_goodB2GSink(short data); + +void CWE190_Integer_Overflow__short_rand_preinc_53c_goodB2GSink(short data) +{ + CWE190_Integer_Overflow__short_rand_preinc_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_postinc_54a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_postinc_54a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_54b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_54_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_54b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_fscanf_postinc_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_54b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_54b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_max_square_64a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_square_64a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_max_square_64b_badSink(void * dataVoidPtr); + +void CWE190_Integer_Overflow__unsigned_int_max_square_64_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + CWE190_Integer_Overflow__unsigned_int_max_square_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_max_square_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_max_square_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_max_square_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + CWE190_Integer_Overflow__unsigned_int_max_square_64b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__unsigned_int_max_square_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_square_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_square_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_add_61a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_add_61a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE190_Integer_Overflow__int_fgets_add_61b_badSource(int data); + +void CWE190_Integer_Overflow__int_fgets_add_61_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_fgets_add_61b_badSource(data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE190_Integer_Overflow__int_fgets_add_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_fgets_add_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE190_Integer_Overflow__int_fgets_add_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE190_Integer_Overflow__int_fgets_add_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__int_fgets_add_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_add_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_add_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_add_16.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_add_16.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_rand_add_16_bad() +{ + short data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + short data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + short result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + short data; + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__short_rand_add_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_add_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_add_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_square_12.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_square_12.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_square_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_square_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_square_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_square_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_multiply_21.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_multiply_21.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int data) +{ + if(badStatic) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_multiply_21_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int data) +{ + if(goodB2G2Static) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int data) +{ + if(goodG2BStatic) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__int_rand_multiply_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_multiply_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_multiply_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_add_21.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_add_21.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_add_21_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE190_Integer_Overflow__int_rand_add_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_add_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_add_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_add_64a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_64a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_64b_badSink(void * dataVoidPtr); + +void CWE190_Integer_Overflow__unsigned_int_rand_add_64_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_add_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_rand_add_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_add_64b_goodB2GSink(&data); +} + +void CWE190_Integer_Overflow__unsigned_int_rand_add_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_add_32.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_add_32.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_add_32_bad() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__int64_t_rand_add_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_add_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_add_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_postinc_12.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_postinc_12.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_listen_socket_postinc_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_listen_socket_postinc_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_postinc_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_postinc_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_multiply_52a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_multiply_52a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_fscanf_multiply_52b_badSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_multiply_52_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_multiply_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_multiply_52b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__short_fscanf_multiply_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_multiply_52b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE190_Integer_Overflow__short_fscanf_multiply_52b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__short_fscanf_multiply_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_multiply_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_multiply_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_postinc_53a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_postinc_53a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fscanf_postinc_53b_badSink(int data); + +void CWE190_Integer_Overflow__int_fscanf_postinc_53_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_postinc_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_53b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fscanf_postinc_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_postinc_53b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE190_Integer_Overflow__int_fscanf_postinc_53b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int_fscanf_postinc_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_max_preinc_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_preinc_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_13_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = UINT_MAX; + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_max_preinc_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_max_preinc_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_postinc_04.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_postinc_04.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_postinc_04_bad() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = SHRT_MAX; + } + if(STATIC_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + short data; + data = 0; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__short_max_postinc_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_max_postinc_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_max_postinc_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_add_12.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_add_12.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_add_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + else + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_add_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_add_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_add_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_multiply_10.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_multiply_10.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_multiply_10_bad() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (LLONG_MAX/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > LLONG_MAX, this will overflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_max_multiply_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_multiply_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_multiply_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_square_11.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_square_11.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_square_11_bad() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > SHRT_MAX, this will overflow */ + short result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)SHRT_MAX)) + { + short result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)SHRT_MAX)) + { + short result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + short data; + data = 0; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > SHRT_MAX, this will overflow */ + short result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: if (data*data) > SHRT_MAX, this will overflow */ + short result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__short_fscanf_square_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_square_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_square_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_add_06.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_add_06.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_add_06_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_max_add_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_add_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_add_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_multiply_41.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_multiply_41.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +void CWE190_Integer_Overflow__char_fscanf_multiply_41_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(char data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goodB2GSink(data); +} + +void CWE190_Integer_Overflow__char_fscanf_multiply_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_multiply_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_multiply_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_multiply_14.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_multiply_14.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_multiply_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalFive==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + } + if(globalFive==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_max_multiply_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_multiply_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_multiply_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_square_02.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_square_02.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_square_02_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(1) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_rand_square_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_square_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_square_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_rand_add_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_add_52c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_rand_add_52c_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_rand_add_52c_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_rand_add_52c_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_fscanf_postinc_68b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_postinc_68b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern short CWE190_Integer_Overflow__short_fscanf_postinc_68_badData; +extern short CWE190_Integer_Overflow__short_fscanf_postinc_68_goodG2BData; +extern short CWE190_Integer_Overflow__short_fscanf_postinc_68_goodB2GData; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_postinc_68b_badSink() +{ + short data = CWE190_Integer_Overflow__short_fscanf_postinc_68_badData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_postinc_68b_goodG2BSink() +{ + short data = CWE190_Integer_Overflow__short_fscanf_postinc_68_goodG2BData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_postinc_68b_goodB2GSink() +{ + short data = CWE190_Integer_Overflow__short_fscanf_postinc_68_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_max_postinc_42.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_postinc_42.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static char badSource(char data) +{ + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + return data; +} + +void CWE190_Integer_Overflow__char_max_postinc_42_bad() +{ + char data; + data = ' '; + data = badSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static char goodG2BSource(char data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +static void goodG2B() +{ + char data; + data = ' '; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static char goodB2GSource(char data) +{ + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + return data; +} + +static void goodB2G() +{ + char data; + data = ' '; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__char_max_postinc_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_postinc_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_postinc_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_square_22b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_square_22b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE190_Integer_Overflow__int64_t_max_square_22_badGlobal; + +void CWE190_Integer_Overflow__int64_t_max_square_22_badSink(int64_t data) +{ + if(CWE190_Integer_Overflow__int64_t_max_square_22_badGlobal) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE190_Integer_Overflow__int64_t_max_square_22_goodB2G1Global; +extern int CWE190_Integer_Overflow__int64_t_max_square_22_goodB2G2Global; +extern int CWE190_Integer_Overflow__int64_t_max_square_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE190_Integer_Overflow__int64_t_max_square_22_goodB2G1Sink(int64_t data) +{ + if(CWE190_Integer_Overflow__int64_t_max_square_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE190_Integer_Overflow__int64_t_max_square_22_goodB2G2Sink(int64_t data) +{ + if(CWE190_Integer_Overflow__int64_t_max_square_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (imaxabs((intmax_t)data) <= sqrtl(LLONG_MAX)) + { + int64_t result = data * data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE190_Integer_Overflow__int64_t_max_square_22_goodG2BSink(int64_t data) +{ + if(CWE190_Integer_Overflow__int64_t_max_square_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: if (data*data) > LLONG_MAX, this will overflow */ + int64_t result = data * data; + printLongLongLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_add_04.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_04.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_add_04_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_TRUE) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_add_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_add_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_add_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_multiply_32.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_multiply_32.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_multiply_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +void CWE190_Integer_Overflow__int_fgets_multiply_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_multiply_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_multiply_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_add_52c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_add_52c.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_add_52c_badSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fscanf_add_52c_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fscanf_add_52c_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_max_preinc_54b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_max_preinc_54b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for unsigned int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54c_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_badSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_max_preinc_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54c_goodG2BSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_goodG2BSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_max_preinc_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54c_goodB2GSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_max_preinc_54b_goodB2GSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_max_preinc_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_rand_postinc_51b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_postinc_51b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_postinc_51b_badSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_postinc_51b_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_postinc_51b_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_fscanf_add_52b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_add_52b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_52c_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_52b_badSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_fscanf_add_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_52c_goodG2BSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_52b_goodG2BSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_fscanf_add_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_52c_goodB2GSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_add_52b_goodB2GSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_fscanf_add_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_fscanf_add_11.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_add_11.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_add_11_bad() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + char result = data + 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char data; + data = ' '; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + char result = data + 1; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_add_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_add_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_add_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_square_14.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_square_14.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_square_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_square_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_square_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_square_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_postinc_61b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_postinc_61b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +char CWE190_Integer_Overflow__char_max_postinc_61b_badSource(char data) +{ + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char CWE190_Integer_Overflow__char_max_postinc_61b_goodG2BSource(char data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +char CWE190_Integer_Overflow__char_max_postinc_61b_goodB2GSource(char data) +{ + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + return data; +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_rand_add_61a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_add_61a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int64_t CWE190_Integer_Overflow__int64_t_rand_add_61b_badSource(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_add_61_bad() +{ + int64_t data; + data = 0LL; + data = CWE190_Integer_Overflow__int64_t_rand_add_61b_badSource(data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int64_t CWE190_Integer_Overflow__int64_t_rand_add_61b_goodG2BSource(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + data = CWE190_Integer_Overflow__int64_t_rand_add_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int64_t result = data + 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int64_t CWE190_Integer_Overflow__int64_t_rand_add_61b_goodB2GSource(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + data = CWE190_Integer_Overflow__int64_t_rand_add_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + int64_t result = data + 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__int64_t_rand_add_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_add_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_add_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_postinc_64b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_postinc_64b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_postinc_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_postinc_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_postinc_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + data++; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__short_fscanf_add_66b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_add_66b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_add_66b_badSink(short dataArray[]) +{ + /* copy data out of dataArray */ + short data = dataArray[2]; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_add_66b_goodG2BSink(short dataArray[]) +{ + short data = dataArray[2]; + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_add_66b_goodB2GSink(short dataArray[]) +{ + short data = dataArray[2]; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + short result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_fscanf_square_32.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_square_32.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_square_32_bad() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + *dataPtr1 = data; + } + { + char data = *dataPtr2; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + *dataPtr1 = data; + } + { + char data = *dataPtr2; + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + *dataPtr1 = data; + } + { + char data = *dataPtr2; + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_square_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_square_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_square_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_multiply_11.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_multiply_11.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_multiply_11_bad() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalReturnsTrue()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (SHRT_MAX/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalReturnsTrue()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (SHRT_MAX/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + short data; + data = 0; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalReturnsTrue()) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__short_fscanf_multiply_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_fscanf_multiply_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_fscanf_multiply_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_max_multiply_03.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_max_multiply_03.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for char + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_max_multiply_03_bad() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = CHAR_MAX; + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (CHAR_MAX/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(5==5) + { + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > CHAR_MAX, this will overflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_max_multiply_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_max_multiply_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_max_multiply_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_max_multiply_65b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_max_multiply_65b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for short + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_max_multiply_65b_badSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_max_multiply_65b_goodG2BSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > SHRT_MAX, this will overflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_max_multiply_65b_goodB2GSink(short data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (SHRT_MAX/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_add_10.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_10.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_add_10_bad() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalTrue) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + unsigned int result = data + 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + unsigned int result = data + 1; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_add_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_multiply_54c.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_multiply_54c.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_max_multiply_54d_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_multiply_54c_badSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_multiply_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_max_multiply_54d_goodG2BSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_multiply_54c_goodG2BSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_multiply_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_max_multiply_54d_goodB2GSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_max_multiply_54c_goodB2GSink(int64_t data) +{ + CWE190_Integer_Overflow__int64_t_max_multiply_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__char_fscanf_square_42.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_square_42.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static char badSource(char data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + return data; +} + +void CWE190_Integer_Overflow__char_fscanf_square_42_bad() +{ + char data; + data = ' '; + data = badSource(data); + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static char goodG2BSource(char data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +static void goodG2B() +{ + char data; + data = ' '; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: if (data*data) > CHAR_MAX, this will overflow */ + char result = data * data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static char goodB2GSource(char data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + return data; +} + +static void goodB2G() +{ + char data; + data = ' '; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) <= (long)sqrt((double)CHAR_MAX)) + { + char result = data * data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__char_fscanf_square_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_square_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_square_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_add_44.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_add_44.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static void badSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_connect_socket_add_44_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = badSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = goodB2GSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + funcPtr(data); +} + +void CWE190_Integer_Overflow__int_connect_socket_add_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_add_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_add_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_square_51b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_square_51b.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_square_51b_badSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_max_square_51b_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_max_square_51b_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_square_51b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_51b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_square_51b_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_51b_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_square_51b_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_preinc_67b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_preinc_67b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE190_Integer_Overflow__int64_t_fscanf_preinc_67_structType +{ + int64_t structFirst; +} CWE190_Integer_Overflow__int64_t_fscanf_preinc_67_structType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_67b_badSink(CWE190_Integer_Overflow__int64_t_fscanf_preinc_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_67b_goodG2BSink(CWE190_Integer_Overflow__int64_t_fscanf_preinc_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_67b_goodB2GSink(CWE190_Integer_Overflow__int64_t_fscanf_preinc_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_postinc_13.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_postinc_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_13_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < UINT_MAX) + { + data++; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_postinc_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_postinc_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_postinc_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_postinc_02.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_postinc_02.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_postinc_02_bad() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + data++; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_max_postinc_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_postinc_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_postinc_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_preinc_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_preinc_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_fscanf_preinc_13_bad() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE190_Integer_Overflow__char_fscanf_preinc_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_preinc_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_square_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_square_54d.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_rand_square_54e_badSink(int data); + +void CWE190_Integer_Overflow__int_rand_square_54d_badSink(int data) +{ + CWE190_Integer_Overflow__int_rand_square_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_rand_square_54e_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_rand_square_54d_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_rand_square_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_rand_square_54e_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_rand_square_54d_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_rand_square_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fgets_postinc_54a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_postinc_54a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_fgets_postinc_54b_badSink(int data); + +void CWE190_Integer_Overflow__int_fgets_postinc_54_bad() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE190_Integer_Overflow__int_fgets_postinc_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_fgets_postinc_54b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_fgets_postinc_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_fgets_postinc_54b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE190_Integer_Overflow__int_fgets_postinc_54b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int_fgets_postinc_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_postinc_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_postinc_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_multiply_54e.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_multiply_54e.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_54e_badSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_54e_goodG2BSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > UINT_MAX, this will overflow */ + unsigned int result = data * 2; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_54e_goodB2GSink(unsigned int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (UINT_MAX/2)) + { + unsigned int result = data * 2; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_postinc_15.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_postinc_15.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_postinc_15_bad() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE190_Integer_Overflow__int_fscanf_postinc_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_postinc_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_square_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_square_54d.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_listen_socket_square_54e_badSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_square_54d_badSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_square_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_54e_goodG2BSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_square_54d_goodG2BSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_square_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_listen_socket_square_54e_goodB2GSink(int data); + +void CWE190_Integer_Overflow__int_listen_socket_square_54d_goodB2GSink(int data) +{ + CWE190_Integer_Overflow__int_listen_socket_square_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_connect_socket_preinc_45.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_preinc_45.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +static int CWE190_Integer_Overflow__int_connect_socket_preinc_45_badData; +static int CWE190_Integer_Overflow__int_connect_socket_preinc_45_goodG2BData; +static int CWE190_Integer_Overflow__int_connect_socket_preinc_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int data = CWE190_Integer_Overflow__int_connect_socket_preinc_45_badData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_connect_socket_preinc_45_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_preinc_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int data = CWE190_Integer_Overflow__int_connect_socket_preinc_45_goodG2BData; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int_connect_socket_preinc_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int data = CWE190_Integer_Overflow__int_connect_socket_preinc_45_goodB2GData; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE190_Integer_Overflow__int_connect_socket_preinc_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE190_Integer_Overflow__int_connect_socket_preinc_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_preinc_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_preinc_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fscanf_multiply_44.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_multiply_44.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +void CWE190_Integer_Overflow__int_fscanf_multiply_44_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = badSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* POTENTIAL FLAW: if (data*2) > INT_MAX, this will overflow */ + int result = data * 2; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + if(data > 0) /* ensure we won't have an underflow */ + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < (INT_MAX/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = goodB2GSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + funcPtr(data); +} + +void CWE190_Integer_Overflow__int_fscanf_multiply_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_multiply_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_multiply_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_multiply_54d.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__char_fscanf_multiply_54e_badSink(char data); + +void CWE190_Integer_Overflow__char_fscanf_multiply_54d_badSink(char data) +{ + CWE190_Integer_Overflow__char_fscanf_multiply_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__char_fscanf_multiply_54e_goodG2BSink(char data); + +void CWE190_Integer_Overflow__char_fscanf_multiply_54d_goodG2BSink(char data) +{ + CWE190_Integer_Overflow__char_fscanf_multiply_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__char_fscanf_multiply_54e_goodB2GSink(char data); + +void CWE190_Integer_Overflow__char_fscanf_multiply_54d_goodB2GSink(char data) +{ + CWE190_Integer_Overflow__char_fscanf_multiply_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_fscanf_preinc_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_preinc_13.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_13_bad() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_fscanf_preinc_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_preinc_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_add_10.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_add_10.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_add_10_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalTrue) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_connect_socket_add_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_add_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_add_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_rand_preinc_34.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_rand_preinc_34.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +typedef union +{ + char unionFirst; + char unionSecond; +} CWE190_Integer_Overflow__char_rand_preinc_34_unionType; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__char_rand_preinc_34_bad() +{ + char data; + CWE190_Integer_Overflow__char_rand_preinc_34_unionType myUnion; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + myUnion.unionFirst = data; + { + char data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + CWE190_Integer_Overflow__char_rand_preinc_34_unionType myUnion; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + myUnion.unionFirst = data; + { + char data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + CWE190_Integer_Overflow__char_rand_preinc_34_unionType myUnion; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + myUnion.unionFirst = data; + { + char data = myUnion.unionSecond; + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + ++data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE190_Integer_Overflow__char_rand_preinc_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_rand_preinc_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_rand_preinc_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_rand_add_16.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_rand_add_16.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_rand_add_16_bad() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__int_rand_add_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_rand_add_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_rand_add_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_fscanf_square_54d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_fscanf_square_54d.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_54e_badSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_54d_badSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_fscanf_square_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_54e_goodG2BSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_54d_goodG2BSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_fscanf_square_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_54e_goodB2GSink(unsigned int data); + +void CWE190_Integer_Overflow__unsigned_int_fscanf_square_54d_goodB2GSink(unsigned int data) +{ + CWE190_Integer_Overflow__unsigned_int_fscanf_square_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__unsigned_int_rand_square_06.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_square_06.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__unsigned_int_rand_square_06_bad() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (abs((long)data) < (long)sqrt((double)UINT_MAX)) + { + unsigned int result = data * data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: if (data*data) > UINT_MAX, this will overflow */ + unsigned int result = data * data; + printUnsignedLine(result); + } + } +} + +void CWE190_Integer_Overflow__unsigned_int_rand_square_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_square_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_listen_socket_postinc_42.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_listen_socket_postinc_42.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static int badSource(int data) +{ + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + return data; +} + +void CWE190_Integer_Overflow__int_listen_socket_postinc_42_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = badSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static int goodG2BSource(int data) +{ + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + return data; +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static int goodB2GSource(int data) +{ + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + return data; +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__int_listen_socket_postinc_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_listen_socket_postinc_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_listen_socket_postinc_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__char_fscanf_postinc_42.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__char_fscanf_postinc_42.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static char badSource(char data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + return data; +} + +void CWE190_Integer_Overflow__char_fscanf_postinc_42_bad() +{ + char data; + data = ' '; + data = badSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static char goodG2BSource(char data) +{ + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + return data; +} + +static void goodG2B() +{ + char data; + data = ' '; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static char goodB2GSource(char data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + return data; +} + +static void goodB2G() +{ + char data; + data = ' '; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < CHAR_MAX) + { + data++; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE190_Integer_Overflow__char_fscanf_postinc_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__char_fscanf_postinc_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__char_fscanf_postinc_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_max_preinc_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_max_preinc_08.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int64_t + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int64_t_max_preinc_08_bad() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use the maximum size of the data type */ + data = LLONG_MAX; + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < LLONG_MAX) + { + ++data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE190_Integer_Overflow__int64_t_max_preinc_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_max_preinc_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_max_preinc_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_fgets_add_03.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fgets_add_03.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fgets_add_03_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + int result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + int result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fgets_add_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fgets_add_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fgets_add_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_connect_socket_postinc_16.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_connect_socket_postinc_16.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_connect_socket_postinc_16_bad() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + } + while(1) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + data++; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + data++; + int result = data; + printIntLine(result); + } + break; + } +} + +void CWE190_Integer_Overflow__int_connect_socket_postinc_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_connect_socket_postinc_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_connect_socket_postinc_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_add_65b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_add_65b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_fscanf_add_65b_badSink(short data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_add_65b_goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_add_65b_goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + short result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_fscanf_preinc_13.c,CWE190,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_fscanf_preinc_13.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_fscanf_preinc_13_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < INT_MAX) + { + ++data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Incrementing data could cause an overflow */ + ++data; + int result = data; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__int_fscanf_preinc_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_fscanf_preinc_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_fscanf_preinc_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_add_68a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_add_68a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_add_68_badData; +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_add_68_goodG2BData; +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_add_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_68b_badSink(); + +void CWE190_Integer_Overflow__unsigned_int_rand_add_68_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_add_68_badData = data; + CWE190_Integer_Overflow__unsigned_int_rand_add_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE190_Integer_Overflow__unsigned_int_rand_add_68b_goodG2BSink(); +void CWE190_Integer_Overflow__unsigned_int_rand_add_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_rand_add_68_goodG2BData = data; + CWE190_Integer_Overflow__unsigned_int_rand_add_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_add_68_goodB2GData = data; + CWE190_Integer_Overflow__unsigned_int_rand_add_68b_goodB2GSink(); +} + +void CWE190_Integer_Overflow__unsigned_int_rand_add_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_add_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__unsigned_int_rand_multiply_68a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__unsigned_int_rand_multiply_68a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: multiply + * GoodSink: Ensure there will not be an overflow before multiplying data by 2 + * BadSink : If data is positive, multiply by 2, which can cause an overflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_badData; +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_goodG2BData; +unsigned int CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_68b_badSink(); + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_badData = data; + CWE190_Integer_Overflow__unsigned_int_rand_multiply_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_68b_goodG2BSink(); +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_goodG2BData = data; + CWE190_Integer_Overflow__unsigned_int_rand_multiply_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_goodB2GData = data; + CWE190_Integer_Overflow__unsigned_int_rand_multiply_68b_goodB2GSink(); +} + +void CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__unsigned_int_rand_multiply_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_fscanf_preinc_52b.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_fscanf_preinc_52b.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__short_fscanf_preinc_52c_badSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_preinc_52b_badSink(short data) +{ + CWE190_Integer_Overflow__short_fscanf_preinc_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__short_fscanf_preinc_52c_goodG2BSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_preinc_52b_goodG2BSink(short data) +{ + CWE190_Integer_Overflow__short_fscanf_preinc_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__short_fscanf_preinc_52c_goodB2GSink(short data); + +void CWE190_Integer_Overflow__short_fscanf_preinc_52b_goodB2GSink(short data) +{ + CWE190_Integer_Overflow__short_fscanf_preinc_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int_max_square_53d.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_square_53d.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__int_max_square_53d_badSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_max_square_53d_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: if (data*data) > INT_MAX, this will overflow */ + int result = data * data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_max_square_53d_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an overflow from occurring */ + if (data > INT_MIN && abs(data) < (long)sqrt((double)INT_MAX)) + { + int result = data * data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE190_Integer_Overflow__int64_t_rand_preinc_65a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_rand_preinc_65a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_65b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_rand_preinc_65_bad() +{ + int64_t data; + /* define a function pointer */ + void (*funcPtr) (int64_t) = CWE190_Integer_Overflow__int64_t_rand_preinc_65b_badSink; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_65b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + void (*funcPtr) (int64_t) = CWE190_Integer_Overflow__int64_t_rand_preinc_65b_goodG2BSink; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_rand_preinc_65b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + void (*funcPtr) (int64_t) = CWE190_Integer_Overflow__int64_t_rand_preinc_65b_goodB2GSink; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + funcPtr(data); +} + +void CWE190_Integer_Overflow__int64_t_rand_preinc_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_rand_preinc_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_rand_preinc_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int_max_square_67a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int_max_square_67a.c +Label Definition File: CWE190_Integer_Overflow__int.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: max Set data to the max value for int + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: square + * GoodSink: Ensure there will not be an overflow before squaring data + * BadSink : Square data, which can lead to overflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE190_Integer_Overflow__int_max_square_67_structType +{ + int structFirst; +} CWE190_Integer_Overflow__int_max_square_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int_max_square_67b_badSink(CWE190_Integer_Overflow__int_max_square_67_structType myStruct); + +void CWE190_Integer_Overflow__int_max_square_67_bad() +{ + int data; + CWE190_Integer_Overflow__int_max_square_67_structType myStruct; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + myStruct.structFirst = data; + CWE190_Integer_Overflow__int_max_square_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int_max_square_67b_goodG2BSink(CWE190_Integer_Overflow__int_max_square_67_structType myStruct); + +static void goodG2B() +{ + int data; + CWE190_Integer_Overflow__int_max_square_67_structType myStruct; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer overflow in the sinks */ + data = 2; + myStruct.structFirst = data; + CWE190_Integer_Overflow__int_max_square_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int_max_square_67b_goodB2GSink(CWE190_Integer_Overflow__int_max_square_67_structType myStruct); + +static void goodB2G() +{ + int data; + CWE190_Integer_Overflow__int_max_square_67_structType myStruct; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the maximum value for this type */ + data = INT_MAX; + myStruct.structFirst = data; + CWE190_Integer_Overflow__int_max_square_67b_goodB2GSink(myStruct); +} + +void CWE190_Integer_Overflow__int_max_square_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int_max_square_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int_max_square_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__short_rand_add_08.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__short_rand_add_08.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: add + * GoodSink: Ensure there will not be an overflow before adding 1 to data + * BadSink : Add 1 to data, which can cause an overflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE190_Integer_Overflow__short_rand_add_08_bad() +{ + short data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + short data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + short result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an overflow from occurring */ + if (data < SHRT_MAX) + { + short result = data + 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + short data; + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Adding 1 to data could cause an overflow */ + short result = data + 1; + printIntLine(result); + } + } +} + +void CWE190_Integer_Overflow__short_rand_add_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__short_rand_add_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__short_rand_add_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE190_Integer_Overflow__int64_t_fscanf_postinc_53a.c,CWE190,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE190_Integer_Overflow__int64_t_fscanf_postinc_53a.c +Label Definition File: CWE190_Integer_Overflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 190 Integer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (two) + * Sinks: increment + * GoodSink: Ensure there will not be an overflow before incrementing data + * BadSink : Increment data, which can cause an overflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_53b_badSink(int64_t data); + +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_53_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_53b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an overflow in the sinks */ + data = 2; + CWE190_Integer_Overflow__int64_t_fscanf_postinc_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_53b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_53b_goodB2GSink(data); +} + +void CWE190_Integer_Overflow__int64_t_fscanf_postinc_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE190_Integer_Overflow__int64_t_fscanf_postinc_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_sub_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_sub_54d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_sub_54e_badSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_sub_54d_badSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_sub_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_sub_54e_goodG2BSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_sub_54d_goodG2BSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_sub_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_sub_54e_goodB2GSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_sub_54d_goodB2GSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_sub_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_predec_41.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_predec_41.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__short_rand_predec_41_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } +} + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + goodB2GSink(data); +} + +void CWE191_Integer_Underflow__short_rand_predec_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_predec_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_predec_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_multiply_13.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_multiply_13_bad() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_multiply_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_predec_15.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_15.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_predec_15_bad() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE191_Integer_Underflow__int_listen_socket_predec_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_min_postdec_01.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_postdec_01.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_min_postdec_01_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__unsigned_int_min_postdec_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_min_postdec_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_min_postdec_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_sub_03.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_sub_03.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_sub_03_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_listen_socket_sub_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_sub_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_sub_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_predec_32.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_predec_32.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_predec_32_bad() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__int64_t_rand_predec_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_postdec_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_postdec_54e.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_min_postdec_54e_badSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_postdec_54e_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_postdec_54e_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_postdec_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_54e.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_postdec_54e_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_54e_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_54e_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_min_sub_14.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_sub_14.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_min_sub_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_min_sub_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_sub_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_sub_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_sub_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_sub_65a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_fscanf_sub_65b_badSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_sub_65_bad() +{ + short data; + /* define a function pointer */ + void (*funcPtr) (short) = CWE191_Integer_Underflow__short_fscanf_sub_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_sub_65b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + void (*funcPtr) (short) = CWE191_Integer_Underflow__short_fscanf_sub_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_sub_65b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + void (*funcPtr) (short) = CWE191_Integer_Underflow__short_fscanf_sub_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + funcPtr(data); +} + +void CWE191_Integer_Underflow__short_fscanf_sub_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_sub_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_sub_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_multiply_03.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_03.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_multiply_03_bad() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(5==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(5==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_multiply_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_multiply_42.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_multiply_42.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static short badSource(short data) +{ + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + return data; +} + +void CWE191_Integer_Underflow__short_min_multiply_42_bad() +{ + short data; + data = 0; + data = badSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static short goodG2BSource(short data) +{ + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + return data; +} + +static void goodG2B() +{ + short data; + data = 0; + data = goodG2BSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static short goodB2GSource(short data) +{ + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + return data; +} + +static void goodB2G() +{ + short data; + data = 0; + data = goodB2GSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +void CWE191_Integer_Underflow__short_min_multiply_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_multiply_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_multiply_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_predec_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_predec_54d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_min_predec_54e_badSink(short data); + +void CWE191_Integer_Underflow__short_min_predec_54d_badSink(short data) +{ + CWE191_Integer_Underflow__short_min_predec_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_predec_54e_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_min_predec_54d_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_min_predec_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_predec_54e_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_min_predec_54d_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_min_predec_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_predec_13.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_predec_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_predec_13_bad() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_rand_predec_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_predec_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_predec_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_predec_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_predec_65a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_predec_65b_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_predec_65_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_connect_socket_predec_65b_badSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_predec_65b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_connect_socket_predec_65b_goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_predec_65b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_connect_socket_predec_65b_goodB2GSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + funcPtr(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_predec_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_predec_10.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_10.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_predec_10_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_listen_socket_predec_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_multiply_44.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_multiply_44.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +void CWE191_Integer_Underflow__char_fscanf_multiply_44_bad() +{ + char data; + /* define a function pointer */ + void (*funcPtr) (char) = badSink; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + void (*funcPtr) (char) = goodG2BSink; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +static void goodB2G() +{ + char data; + void (*funcPtr) (char) = goodB2GSink; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + funcPtr(data); +} + +void CWE191_Integer_Underflow__char_fscanf_multiply_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_multiply_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_multiply_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_sub_05.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_sub_05.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_05_bad() +{ + int64_t data; + data = 0LL; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(staticTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_predec_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_66a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_predec_66b_badSink(char dataArray[]); + +void CWE191_Integer_Underflow__char_rand_predec_66_bad() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__char_rand_predec_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_predec_66b_goodG2BSink(char dataArray[]); + +static void goodG2B() +{ + char data; + char dataArray[5]; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__char_rand_predec_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_predec_66b_goodB2GSink(char dataArray[]); + +static void goodB2G() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + dataArray[2] = data; + CWE191_Integer_Underflow__char_rand_predec_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__char_rand_predec_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_predec_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_predec_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_rand_predec_09.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_predec_09.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_predec_09_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_rand_predec_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_rand_predec_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_rand_predec_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_sub_44.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_44.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static void badSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_44_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = badSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = goodB2GSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + funcPtr(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_sub_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_66a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_sub_66b_badSink(int dataArray[]); + +void CWE191_Integer_Underflow__int_connect_socket_sub_66_bad() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__int_connect_socket_sub_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_66b_goodG2BSink(int dataArray[]); + +static void goodG2B() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__int_connect_socket_sub_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_66b_goodB2GSink(int dataArray[]); + +static void goodB2G() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + dataArray[2] = data; + CWE191_Integer_Underflow__int_connect_socket_sub_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_multiply_53a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_multiply_53a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_53b_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_53_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%lld"", &data); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_53b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_fscanf_multiply_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_53b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%lld"", &data); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_53b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_sub_53d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_53d.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_sub_53d_badSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_53d_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_53d_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_fscanf_multiply_15.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_multiply_15.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_15_bad() +{ + int64_t data; + data = 0LL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_postdec_34.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_postdec_34.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef union +{ + int unionFirst; + int unionSecond; +} CWE191_Integer_Underflow__int_connect_socket_postdec_34_unionType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_postdec_34_bad() +{ + int data; + CWE191_Integer_Underflow__int_connect_socket_postdec_34_unionType myUnion; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + CWE191_Integer_Underflow__int_connect_socket_postdec_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + CWE191_Integer_Underflow__int_connect_socket_postdec_34_unionType myUnion; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_postdec_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_multiply_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_53c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_fscanf_multiply_53d_badSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_53c_badSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_multiply_53d_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_53c_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_multiply_53d_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_53c_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_51b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_51b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_fscanf_multiply_65b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_multiply_65b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_multiply_65b_badSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_65b_goodG2BSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_65b_goodB2GSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_listen_socket_predec_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_63b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_predec_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_predec_17.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_predec_17.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_predec_17_bad() +{ + int i,j; + short data; + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + short data; + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + short data; + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_rand_predec_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_predec_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_predec_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fscanf_postdec_34.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_postdec_34.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +typedef union +{ + int unionFirst; + int unionSecond; +} CWE191_Integer_Underflow__int_fscanf_postdec_34_unionType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fscanf_postdec_34_bad() +{ + int data; + CWE191_Integer_Underflow__int_fscanf_postdec_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + CWE191_Integer_Underflow__int_fscanf_postdec_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + CWE191_Integer_Underflow__int_fscanf_postdec_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__int_fscanf_postdec_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_postdec_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_postdec_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_multiply_54c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_multiply_54c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_multiply_54d_badSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_multiply_54c_badSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_multiply_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_54d_goodG2BSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_multiply_54c_goodG2BSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_multiply_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_54d_goodB2GSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_multiply_54c_goodB2GSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_multiply_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_postdec_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_53c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_min_postdec_53d_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_postdec_53c_badSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_postdec_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_53d_goodG2BSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_postdec_53c_goodG2BSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_postdec_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_53d_goodB2GSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_postdec_53c_goodB2GSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_postdec_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_postdec_21.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_postdec_21.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_postdec_21_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_postdec_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_multiply_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_multiply_66a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_min_multiply_66b_badSink(int dataArray[]); + +void CWE191_Integer_Underflow__int_min_multiply_66_bad() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__int_min_multiply_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_multiply_66b_goodG2BSink(int dataArray[]); + +static void goodG2B() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__int_min_multiply_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_multiply_66b_goodB2GSink(int dataArray[]); + +static void goodB2G() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + dataArray[2] = data; + CWE191_Integer_Underflow__int_min_multiply_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__int_min_multiply_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_multiply_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_multiply_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_sub_06.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_sub_06.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_sub_06_bad() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_sub_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_sub_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_sub_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_multiply_54b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_multiply_54b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_rand_multiply_54c_badSink(short data); + +void CWE191_Integer_Underflow__short_rand_multiply_54b_badSink(short data) +{ + CWE191_Integer_Underflow__short_rand_multiply_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_multiply_54c_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_rand_multiply_54b_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_rand_multiply_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_multiply_54c_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_rand_multiply_54b_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_rand_multiply_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_51a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_51a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_51_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE191_Integer_Underflow__unsigned_int_rand_predec_51b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_sub_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_sub_52a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_min_sub_52b_badSink(char data); + +void CWE191_Integer_Underflow__char_min_sub_52_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_sub_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_sub_52b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_min_sub_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_sub_52b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_sub_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_min_sub_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_sub_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_sub_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_multiply_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_53c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_min_multiply_53d_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_multiply_53c_badSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_multiply_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_multiply_53d_goodG2BSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_multiply_53c_goodG2BSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_multiply_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_multiply_53d_goodB2GSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_multiply_53c_goodB2GSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_multiply_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_predec_07.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_predec_07.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-07.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + any other value so a tool should be able to identify that reads of + this will always give its initialized value. */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_predec_07_bad() +{ + int64_t data; + data = 0LL; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticFive==5 to staticFive!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(staticFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_rand_predec_07_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_predec_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_predec_65a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_rand_predec_65b_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_rand_predec_65_bad() +{ + int64_t data; + /* define a function pointer */ + void (*funcPtr) (int64_t) = CWE191_Integer_Underflow__int64_t_rand_predec_65b_badSink; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_predec_65b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + void (*funcPtr) (int64_t) = CWE191_Integer_Underflow__int64_t_rand_predec_65b_goodG2BSink; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_predec_65b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + void (*funcPtr) (int64_t) = CWE191_Integer_Underflow__int64_t_rand_predec_65b_goodB2GSink; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + funcPtr(data); +} + +void CWE191_Integer_Underflow__int64_t_rand_predec_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_predec_09.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_predec_09.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_predec_09_bad() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_min_predec_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_predec_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_predec_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_postdec_67a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_67a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__char_rand_postdec_67_structType +{ + char structFirst; +} CWE191_Integer_Underflow__char_rand_postdec_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_postdec_67b_badSink(CWE191_Integer_Underflow__char_rand_postdec_67_structType myStruct); + +void CWE191_Integer_Underflow__char_rand_postdec_67_bad() +{ + char data; + CWE191_Integer_Underflow__char_rand_postdec_67_structType myStruct; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_rand_postdec_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_postdec_67b_goodG2BSink(CWE191_Integer_Underflow__char_rand_postdec_67_structType myStruct); + +static void goodG2B() +{ + char data; + CWE191_Integer_Underflow__char_rand_postdec_67_structType myStruct; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_rand_postdec_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_postdec_67b_goodB2GSink(CWE191_Integer_Underflow__char_rand_postdec_67_structType myStruct); + +static void goodB2G() +{ + char data; + CWE191_Integer_Underflow__char_rand_postdec_67_structType myStruct; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_rand_postdec_67b_goodB2GSink(myStruct); +} + +void CWE191_Integer_Underflow__char_rand_postdec_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_multiply_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_52c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_multiply_52c_badSink(int64_t data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_multiply_52c_goodG2BSink(int64_t data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_multiply_52c_goodB2GSink(int64_t data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_multiply_53d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_53d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_multiply_53d_badSink(int64_t data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_multiply_53d_goodG2BSink(int64_t data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_multiply_53d_goodB2GSink(int64_t data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fscanf_predec_53a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_predec_53a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fscanf_predec_53b_badSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_predec_53_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE191_Integer_Underflow__int_fscanf_predec_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fscanf_predec_53b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_fscanf_predec_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fscanf_predec_53b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE191_Integer_Underflow__int_fscanf_predec_53b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_fscanf_predec_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_predec_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_predec_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_sub_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_sub_52a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_sub_52b_badSink(char data); + +void CWE191_Integer_Underflow__char_rand_sub_52_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_sub_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_sub_52b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_rand_sub_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_sub_52b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_sub_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_rand_sub_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_sub_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_sub_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_sub_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_sub_22b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__int_min_sub_22_badGlobal; + +void CWE191_Integer_Underflow__int_min_sub_22_badSink(int data) +{ + if(CWE191_Integer_Underflow__int_min_sub_22_badGlobal) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__int_min_sub_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__int_min_sub_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__int_min_sub_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__int_min_sub_22_goodB2G1Sink(int data) +{ + if(CWE191_Integer_Underflow__int_min_sub_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__int_min_sub_22_goodB2G2Sink(int data) +{ + if(CWE191_Integer_Underflow__int_min_sub_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__int_min_sub_22_goodG2BSink(int data) +{ + if(CWE191_Integer_Underflow__int_min_sub_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fscanf_predec_68a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_predec_68a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +int CWE191_Integer_Underflow__int_fscanf_predec_68_badData; +int CWE191_Integer_Underflow__int_fscanf_predec_68_goodG2BData; +int CWE191_Integer_Underflow__int_fscanf_predec_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fscanf_predec_68b_badSink(); + +void CWE191_Integer_Underflow__int_fscanf_predec_68_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE191_Integer_Underflow__int_fscanf_predec_68_badData = data; + CWE191_Integer_Underflow__int_fscanf_predec_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE191_Integer_Underflow__int_fscanf_predec_68b_goodG2BSink(); +void CWE191_Integer_Underflow__int_fscanf_predec_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_fscanf_predec_68_goodG2BData = data; + CWE191_Integer_Underflow__int_fscanf_predec_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE191_Integer_Underflow__int_fscanf_predec_68_goodB2GData = data; + CWE191_Integer_Underflow__int_fscanf_predec_68b_goodB2GSink(); +} + +void CWE191_Integer_Underflow__int_fscanf_predec_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_predec_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_predec_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_postdec_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_61a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int64_t CWE191_Integer_Underflow__int64_t_min_postdec_61b_badSource(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_postdec_61_bad() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_postdec_61b_badSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int64_t CWE191_Integer_Underflow__int64_t_min_postdec_61b_goodG2BSource(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_postdec_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int64_t CWE191_Integer_Underflow__int64_t_min_postdec_61b_goodB2GSource(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_postdec_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__int64_t_min_postdec_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_postdec_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_postdec_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_sub_53d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_sub_53d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_sub_53d_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_53d_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_53d_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_sub_63a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_sub_63a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_min_sub_63b_badSink(int64_t * dataPtr); + +void CWE191_Integer_Underflow__int64_t_min_sub_63_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + CWE191_Integer_Underflow__int64_t_min_sub_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_sub_63b_goodG2BSink(int64_t * data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_min_sub_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_sub_63b_goodB2GSink(int64_t * data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + CWE191_Integer_Underflow__int64_t_min_sub_63b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__int64_t_min_sub_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_sub_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_sub_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_postdec_17.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_17.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_postdec_17_bad() +{ + int i,j; + char data; + data = ' '; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + char data; + data = ' '; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + char data; + data = ' '; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_postdec_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_min_sub_07.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_sub_07.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-07.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + any other value so a tool should be able to identify that reads of + this will always give its initialized value. */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_min_sub_07_bad() +{ + unsigned int data; + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticFive==5 to staticFive!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(staticFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(staticFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_min_sub_07_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_min_sub_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_min_sub_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_postdec_16.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_postdec_16.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_postdec_16_bad() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + break; + } + while(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + break; + } +} + +void CWE191_Integer_Underflow__int_fgets_postdec_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_postdec_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_postdec_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_predec_08.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_predec_08.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_predec_08_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_predec_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_min_sub_61b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_sub_61b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +unsigned int CWE191_Integer_Underflow__unsigned_int_min_sub_61b_badSource(unsigned int data) +{ + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +unsigned int CWE191_Integer_Underflow__unsigned_int_min_sub_61b_goodG2BSource(unsigned int data) +{ + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +unsigned int CWE191_Integer_Underflow__unsigned_int_min_sub_61b_goodB2GSource(unsigned int data) +{ + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + return data; +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_multiply_41.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_multiply_41.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static void badSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_connect_socket_multiply_41_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_multiply_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53b_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_multiply_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_multiply_54d.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_54e_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_multiply_54d_badSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_multiply_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_54e_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_multiply_54d_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_multiply_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_54e_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_multiply_54d_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_multiply_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_predec_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_53c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_predec_53d_badSink(char data); + +void CWE191_Integer_Underflow__char_rand_predec_53c_badSink(char data) +{ + CWE191_Integer_Underflow__char_rand_predec_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_predec_53d_goodG2BSink(char data); + +void CWE191_Integer_Underflow__char_rand_predec_53c_goodG2BSink(char data) +{ + CWE191_Integer_Underflow__char_rand_predec_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_predec_53d_goodB2GSink(char data); + +void CWE191_Integer_Underflow__char_rand_predec_53c_goodB2GSink(char data) +{ + CWE191_Integer_Underflow__char_rand_predec_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_multiply_03.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_multiply_03.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_multiply_03_bad() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(5==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_rand_multiply_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_multiply_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_multiply_52a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_52b_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_multiply_52_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_connect_socket_multiply_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_52b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_connect_socket_multiply_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_52b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_connect_socket_multiply_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_multiply_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_predec_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_predec_22b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__int_fgets_predec_22_badGlobal; + +void CWE191_Integer_Underflow__int_fgets_predec_22_badSink(int data) +{ + if(CWE191_Integer_Underflow__int_fgets_predec_22_badGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__int_fgets_predec_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__int_fgets_predec_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__int_fgets_predec_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__int_fgets_predec_22_goodB2G1Sink(int data) +{ + if(CWE191_Integer_Underflow__int_fgets_predec_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__int_fgets_predec_22_goodB2G2Sink(int data) +{ + if(CWE191_Integer_Underflow__int_fgets_predec_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__int_fgets_predec_22_goodG2BSink(int data) +{ + if(CWE191_Integer_Underflow__int_fgets_predec_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_multiply_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_multiply_64b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_multiply_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_multiply_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_multiply_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_listen_socket_sub_65b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_sub_65b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_sub_65b_badSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_sub_65b_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_sub_65b_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_postdec_21.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_21.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int64_t data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_postdec_21_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int64_t data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int64_t data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int64_t data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE191_Integer_Underflow__int64_t_min_postdec_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_postdec_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_postdec_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_multiply_18.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_multiply_18.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_multiply_18_bad() +{ + short data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + short data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + short data; + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__short_rand_multiply_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_multiply_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_multiply_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_predec_18.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_predec_18.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_predec_18_bad() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_connect_socket_predec_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_multiply_18.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_multiply_18.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_multiply_18_bad() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_listen_socket_multiply_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_rand_multiply_67a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_multiply_67a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__int_rand_multiply_67_structType +{ + int structFirst; +} CWE191_Integer_Underflow__int_rand_multiply_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_rand_multiply_67b_badSink(CWE191_Integer_Underflow__int_rand_multiply_67_structType myStruct); + +void CWE191_Integer_Underflow__int_rand_multiply_67_bad() +{ + int data; + CWE191_Integer_Underflow__int_rand_multiply_67_structType myStruct; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_rand_multiply_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_multiply_67b_goodG2BSink(CWE191_Integer_Underflow__int_rand_multiply_67_structType myStruct); + +static void goodG2B() +{ + int data; + CWE191_Integer_Underflow__int_rand_multiply_67_structType myStruct; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_rand_multiply_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_multiply_67b_goodB2GSink(CWE191_Integer_Underflow__int_rand_multiply_67_structType myStruct); + +static void goodB2G() +{ + int data; + CWE191_Integer_Underflow__int_rand_multiply_67_structType myStruct; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_rand_multiply_67b_goodB2GSink(myStruct); +} + +void CWE191_Integer_Underflow__int_rand_multiply_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_rand_multiply_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_rand_multiply_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_multiply_04.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_multiply_04.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_multiply_04_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_TRUE) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_TRUE) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_TRUE) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_fgets_multiply_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_multiply_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_multiply_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_predec_01.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_predec_01.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_01_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_predec_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_predec_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_sub_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_sub_65a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_min_sub_65b_badSink(int data); + +void CWE191_Integer_Underflow__int_min_sub_65_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_min_sub_65b_badSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_sub_65b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_min_sub_65b_goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_sub_65b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_min_sub_65b_goodB2GSink; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + funcPtr(data); +} + +void CWE191_Integer_Underflow__int_min_sub_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_sub_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_sub_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_multiply_13.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_multiply_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_multiply_13_bad() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_min_multiply_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_multiply_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_multiply_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_predec_53b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_53b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_listen_socket_predec_53c_badSink(int data); + +void CWE191_Integer_Underflow__int_listen_socket_predec_53b_badSink(int data) +{ + CWE191_Integer_Underflow__int_listen_socket_predec_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_53c_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_listen_socket_predec_53b_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_listen_socket_predec_53c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_53c_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_listen_socket_predec_53b_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_listen_socket_predec_53c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_61b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_61b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +unsigned int CWE191_Integer_Underflow__unsigned_int_rand_sub_61b_badSource(unsigned int data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +unsigned int CWE191_Integer_Underflow__unsigned_int_rand_sub_61b_goodG2BSource(unsigned int data) +{ + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +unsigned int CWE191_Integer_Underflow__unsigned_int_rand_sub_61b_goodB2GSource(unsigned int data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + return data; +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_multiply_12.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_multiply_12.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_multiply_12_bad() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + else + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(globalReturnsTrueOrFalse()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_rand_multiply_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_multiply_54c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_multiply_54c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_min_multiply_54d_badSink(short data); + +void CWE191_Integer_Underflow__short_min_multiply_54c_badSink(short data) +{ + CWE191_Integer_Underflow__short_min_multiply_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_multiply_54d_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_min_multiply_54c_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_min_multiply_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_multiply_54d_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_min_multiply_54c_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_min_multiply_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_min_sub_10.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_sub_10.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_min_sub_10_bad() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(globalTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_min_sub_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_min_sub_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_min_sub_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_multiply_66b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_multiply_66b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_multiply_66b_badSink(char dataArray[]) +{ + /* copy data out of dataArray */ + char data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_66b_goodG2BSink(char dataArray[]) +{ + char data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_66b_goodB2GSink(char dataArray[]) +{ + char data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_postdec_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_postdec_63b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_postdec_63b_badSink(short * dataPtr) +{ + short data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_postdec_63b_goodG2BSink(short * dataPtr) +{ + short data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_postdec_63b_goodB2GSink(short * dataPtr) +{ + short data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_66b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_66b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_66b_badSink(unsigned int dataArray[]) +{ + /* copy data out of dataArray */ + unsigned int data = dataArray[2]; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_66b_goodG2BSink(unsigned int dataArray[]) +{ + unsigned int data = dataArray[2]; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_66b_goodB2GSink(unsigned int dataArray[]) +{ + unsigned int data = dataArray[2]; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_listen_socket_multiply_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_multiply_64b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_multiply_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_multiply_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_multiply_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_structType +{ + unsigned int structFirst; +} CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67b_badSink(CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_structType myStruct); + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_bad() +{ + unsigned int data; + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_structType myStruct; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + myStruct.structFirst = data; + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67b_goodG2BSink(CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_structType myStruct); + +static void goodG2B() +{ + unsigned int data; + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_structType myStruct; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + myStruct.structFirst = data; + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67b_goodB2GSink(CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_structType myStruct); + +static void goodB2G() +{ + unsigned int data; + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_structType myStruct; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + myStruct.structFirst = data; + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67b_goodB2GSink(myStruct); +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_sub_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_sub_53c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_min_sub_53d_badSink(short data); + +void CWE191_Integer_Underflow__short_min_sub_53c_badSink(short data) +{ + CWE191_Integer_Underflow__short_min_sub_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_sub_53d_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_min_sub_53c_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_min_sub_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_sub_53d_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_min_sub_53c_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_min_sub_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_min_predec_52b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_predec_52b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_min_predec_52c_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_min_predec_52b_badSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_min_predec_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_min_predec_52c_goodG2BSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_min_predec_52b_goodG2BSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_min_predec_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_min_predec_52c_goodB2GSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_min_predec_52b_goodB2GSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_min_predec_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_min_multiply_51b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_multiply_51b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_multiply_51b_badSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_multiply_51b_goodG2BSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_multiply_51b_goodB2GSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_fscanf_predec_01.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_predec_01.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_predec_01_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__char_fscanf_predec_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_predec_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_predec_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_postdec_51a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_51a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_postdec_51b_badSink(char data); + +void CWE191_Integer_Underflow__char_rand_postdec_51_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_postdec_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_postdec_51b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_rand_postdec_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_postdec_51b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_postdec_51b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_rand_postdec_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_multiply_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_multiply_22b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__int_listen_socket_multiply_22_badGlobal; + +void CWE191_Integer_Underflow__int_listen_socket_multiply_22_badSink(int data) +{ + if(CWE191_Integer_Underflow__int_listen_socket_multiply_22_badGlobal) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodB2G1Sink(int data) +{ + if(CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodB2G2Sink(int data) +{ + if(CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodB2G2Global) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodG2BSink(int data) +{ + if(CWE191_Integer_Underflow__int_listen_socket_multiply_22_goodG2BGlobal) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_postdec_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_postdec_52c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_postdec_52c_badSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_postdec_52c_goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_postdec_52c_goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fscanf_postdec_08.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_postdec_08.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fscanf_postdec_08_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_fscanf_postdec_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_postdec_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_postdec_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_sub_65b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_sub_65b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_sub_65b_badSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_sub_65b_goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_sub_65b_goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_multiply_13.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_multiply_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_multiply_13_bad() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_rand_multiply_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_multiply_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_multiply_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_sub_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_sub_22b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__short_min_sub_22_badGlobal; + +void CWE191_Integer_Underflow__short_min_sub_22_badSink(short data) +{ + if(CWE191_Integer_Underflow__short_min_sub_22_badGlobal) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__short_min_sub_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__short_min_sub_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__short_min_sub_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__short_min_sub_22_goodB2G1Sink(short data) +{ + if(CWE191_Integer_Underflow__short_min_sub_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__short_min_sub_22_goodB2G2Sink(short data) +{ + if(CWE191_Integer_Underflow__short_min_sub_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__short_min_sub_22_goodG2BSink(short data) +{ + if(CWE191_Integer_Underflow__short_min_sub_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_fscanf_predec_03.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_predec_03.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_predec_03_bad() +{ + short data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(5==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_predec_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_predec_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_predec_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_rand_sub_65b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_sub_65b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_sub_65b_badSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_sub_65b_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_sub_65b_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_sub_45.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_sub_45.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static char CWE191_Integer_Underflow__char_rand_sub_45_badData; +static char CWE191_Integer_Underflow__char_rand_sub_45_goodG2BData; +static char CWE191_Integer_Underflow__char_rand_sub_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + char data = CWE191_Integer_Underflow__char_rand_sub_45_badData; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +void CWE191_Integer_Underflow__char_rand_sub_45_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_sub_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char data = CWE191_Integer_Underflow__char_rand_sub_45_goodG2BData; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_rand_sub_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + char data = CWE191_Integer_Underflow__char_rand_sub_45_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_sub_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__char_rand_sub_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_sub_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_sub_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_postdec_18.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_postdec_18.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_postdec_18_bad() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_fgets_postdec_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_postdec_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_postdec_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_03.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_03.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_03_bad() +{ + unsigned int data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(5==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(5==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_postdec_54a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_postdec_54a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_min_postdec_54b_badSink(char data); + +void CWE191_Integer_Underflow__char_min_postdec_54_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_postdec_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_postdec_54b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_min_postdec_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_postdec_54b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_postdec_54b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_min_postdec_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_postdec_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_postdec_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_multiply_31.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_31.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_multiply_31_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + { + short dataCopy = data; + short data = dataCopy; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + { + short dataCopy = data; + short data = dataCopy; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + { + short dataCopy = data; + short data = dataCopy; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_multiply_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_postdec_15.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_postdec_15.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_postdec_15_bad() +{ + char data; + data = ' '; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + char data; + data = ' '; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + char data; + data = ' '; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + char data; + data = ' '; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + char data; + data = ' '; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE191_Integer_Underflow__char_fscanf_postdec_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_postdec_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_postdec_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_multiply_15.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_multiply_15.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_multiply_15_bad() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + short data; + data = 0; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE191_Integer_Underflow__short_rand_multiply_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_multiply_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_multiply_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_predec_05.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_predec_05.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_predec_05_bad() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(staticTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + short data; + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_predec_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_predec_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_predec_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_min_sub_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_sub_54d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_min_sub_54e_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_min_sub_54d_badSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_min_sub_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_min_sub_54e_goodG2BSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_min_sub_54d_goodG2BSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_min_sub_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_min_sub_54e_goodB2GSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_min_sub_54d_goodB2GSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_min_sub_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_fscanf_predec_05.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_predec_05.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_predec_05_bad() +{ + char data; + data = ' '; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + char data; + data = ' '; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(staticTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + char data; + data = ' '; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_fscanf_predec_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_predec_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_predec_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_predec_53d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_predec_53d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_predec_53d_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_predec_53d_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_predec_53d_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_predec_04.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_predec_04.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_predec_04_bad() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_TRUE) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + short data; + data = 0; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_min_predec_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_predec_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_predec_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_multiply_66b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_multiply_66b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_multiply_66b_badSink(int dataArray[]) +{ + /* copy data out of dataArray */ + int data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_multiply_66b_goodG2BSink(int dataArray[]) +{ + int data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_multiply_66b_goodB2GSink(int dataArray[]) +{ + int data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_min_predec_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_predec_22b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__int_min_predec_22_badGlobal; + +void CWE191_Integer_Underflow__int_min_predec_22_badSink(int data) +{ + if(CWE191_Integer_Underflow__int_min_predec_22_badGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__int_min_predec_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__int_min_predec_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__int_min_predec_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__int_min_predec_22_goodB2G1Sink(int data) +{ + if(CWE191_Integer_Underflow__int_min_predec_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__int_min_predec_22_goodB2G2Sink(int data) +{ + if(CWE191_Integer_Underflow__int_min_predec_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__int_min_predec_22_goodG2BSink(int data) +{ + if(CWE191_Integer_Underflow__int_min_predec_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_sub_08.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_08.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_sub_08_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_multiply_02.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_multiply_02.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_min_multiply_02_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_min_multiply_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_multiply_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_multiply_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_multiply_45.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_multiply_45.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static short CWE191_Integer_Underflow__short_rand_multiply_45_badData; +static short CWE191_Integer_Underflow__short_rand_multiply_45_goodG2BData; +static short CWE191_Integer_Underflow__short_rand_multiply_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + short data = CWE191_Integer_Underflow__short_rand_multiply_45_badData; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__short_rand_multiply_45_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE191_Integer_Underflow__short_rand_multiply_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + short data = CWE191_Integer_Underflow__short_rand_multiply_45_goodG2BData; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__short_rand_multiply_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + short data = CWE191_Integer_Underflow__short_rand_multiply_45_goodB2GData; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE191_Integer_Underflow__short_rand_multiply_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__short_rand_multiply_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_multiply_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_multiply_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_rand_predec_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_predec_63b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_predec_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_predec_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_predec_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_postdec_54b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_54b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_min_postdec_54c_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_postdec_54b_badSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_postdec_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_54c_goodG2BSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_postdec_54b_goodG2BSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_postdec_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_54c_goodB2GSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_postdec_54b_goodB2GSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_min_postdec_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_sub_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_sub_52c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_sub_52c_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_52c_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_52c_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fscanf_predec_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_predec_54e.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fscanf_predec_54e_badSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fscanf_predec_54e_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fscanf_predec_54e_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fgets_postdec_10.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_postdec_10.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_postdec_10_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_fgets_postdec_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_postdec_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_postdec_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_postdec_32.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_postdec_32.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_postdec_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_postdec_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_postdec_12.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_12.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_postdec_12_bad() +{ + char data; + data = ' '; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + else + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_postdec_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_sub_63a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_sub_63a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_rand_sub_63b_badSink(int64_t * dataPtr); + +void CWE191_Integer_Underflow__int64_t_rand_sub_63_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_sub_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_63b_goodG2BSink(int64_t * data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_rand_sub_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_63b_goodB2GSink(int64_t * data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_sub_63b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__int64_t_rand_sub_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_sub_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_sub_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_predec_54a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_54a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_predec_54b_badSink(char data); + +void CWE191_Integer_Underflow__char_rand_predec_54_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_predec_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_predec_54b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_rand_predec_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_predec_54b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_predec_54b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_rand_predec_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_predec_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_predec_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fscanf_postdec_53b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_postdec_53b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fscanf_postdec_53c_badSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_postdec_53b_badSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_postdec_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fscanf_postdec_53c_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_postdec_53b_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_postdec_53c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fscanf_postdec_53c_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_postdec_53b_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_postdec_53c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_fscanf_predec_13.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_predec_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_13_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_predec_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_predec_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_postdec_54a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_postdec_54a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_postdec_54b_badSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_postdec_54_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_postdec_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_postdec_54b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_fscanf_postdec_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_postdec_54b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_postdec_54b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_fscanf_postdec_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_postdec_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_postdec_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_multiply_66b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_multiply_66b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_multiply_66b_badSink(char dataArray[]) +{ + /* copy data out of dataArray */ + char data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_multiply_66b_goodG2BSink(char dataArray[]) +{ + char data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_multiply_66b_goodB2GSink(char dataArray[]) +{ + char data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_min_predec_66b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_predec_66b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_min_predec_66b_badSink(int dataArray[]) +{ + /* copy data out of dataArray */ + int data = dataArray[2]; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_predec_66b_goodG2BSink(int dataArray[]) +{ + int data = dataArray[2]; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_predec_66b_goodB2GSink(int dataArray[]) +{ + int data = dataArray[2]; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_min_sub_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_sub_54e.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_sub_54e_badSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_sub_54e_goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_sub_54e_goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fgets_sub_42.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_sub_42.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static int badSource(int data) +{ + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + return data; +} + +void CWE191_Integer_Underflow__int_fgets_sub_42_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = badSource(data); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static int goodG2BSource(int data) +{ + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + return data; +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static int goodB2GSource(int data) +{ + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + return data; +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +void CWE191_Integer_Underflow__int_fgets_sub_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_sub_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_sub_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67_structType +{ + unsigned int structFirst; +} CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67b_badSink(CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67b_goodG2BSink(CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67b_goodB2GSink(CWE191_Integer_Underflow__unsigned_int_fscanf_predec_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_listen_socket_multiply_32.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_multiply_32.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_multiply_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +void CWE191_Integer_Underflow__int_listen_socket_multiply_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_postdec_61b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_61b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +char CWE191_Integer_Underflow__char_rand_postdec_61b_badSource(char data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char CWE191_Integer_Underflow__char_rand_postdec_61b_goodG2BSource(char data) +{ + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +char CWE191_Integer_Underflow__char_rand_postdec_61b_goodB2GSource(char data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + return data; +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_min_sub_21.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_sub_21.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_min_sub_21_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE191_Integer_Underflow__int_min_sub_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_sub_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_sub_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_postdec_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_postdec_67b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__unsigned_int_rand_postdec_67_structType +{ + unsigned int structFirst; +} CWE191_Integer_Underflow__unsigned_int_rand_postdec_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_67b_badSink(CWE191_Integer_Underflow__unsigned_int_rand_postdec_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_67b_goodG2BSink(CWE191_Integer_Underflow__unsigned_int_rand_postdec_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_67b_goodB2GSink(CWE191_Integer_Underflow__unsigned_int_rand_postdec_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_multiply_65b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_multiply_65b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_multiply_65b_badSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_multiply_65b_goodG2BSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_multiply_65b_goodB2GSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_fscanf_predec_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_predec_52a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_predec_52b_badSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_predec_52_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_predec_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_52b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_fscanf_predec_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_52b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_predec_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_fscanf_predec_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_predec_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_predec_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_postdec_31.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_postdec_31.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_postdec_31_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + { + short dataCopy = data; + short data = dataCopy; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + { + short dataCopy = data; + short data = dataCopy; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + { + short dataCopy = data; + short data = dataCopy; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__short_min_postdec_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_postdec_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_postdec_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_multiply_41.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_multiply_41.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static void badSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_listen_socket_multiply_41_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_listen_socket_multiply_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_predec_02.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_predec_02.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_predec_02_bad() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_predec_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_predec_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_predec_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_sub_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_sub_63b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_sub_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_sub_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_sub_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_multiply_08.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_multiply_08.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_multiply_08_bad() +{ + char data; + data = ' '; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticReturnsTrue()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + char data; + data = ' '; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticReturnsTrue()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char data; + data = ' '; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_multiply_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_multiply_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_multiply_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_sub_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_sub_64b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_sub_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_sub_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_sub_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_multiply_05.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_multiply_05.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_multiply_05_bad() +{ + int64_t data; + data = 0LL; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_rand_multiply_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_min_predec_12.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_predec_12.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_min_predec_12_bad() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + else + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_min_predec_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_min_predec_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_min_predec_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_sub_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_sub_67b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__int64_t_rand_sub_67_structType +{ + int64_t structFirst; +} CWE191_Integer_Underflow__int64_t_rand_sub_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_sub_67b_badSink(CWE191_Integer_Underflow__int64_t_rand_sub_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_67b_goodG2BSink(CWE191_Integer_Underflow__int64_t_rand_sub_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_67b_goodB2GSink(CWE191_Integer_Underflow__int64_t_rand_sub_67_structType myStruct) +{ + int64_t data = myStruct.structFirst; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_multiply_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_multiply_52c.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_multiply_52c_badSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_52c_goodG2BSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_52c_goodB2GSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_fscanf_postdec_17.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_postdec_17.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_postdec_17_bad() +{ + int i,j; + short data; + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + short data; + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + short data; + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_postdec_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_postdec_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_postdec_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_multiply_68a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_multiply_68a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +char CWE191_Integer_Underflow__char_min_multiply_68_badData; +char CWE191_Integer_Underflow__char_min_multiply_68_goodG2BData; +char CWE191_Integer_Underflow__char_min_multiply_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_min_multiply_68b_badSink(); + +void CWE191_Integer_Underflow__char_min_multiply_68_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_multiply_68_badData = data; + CWE191_Integer_Underflow__char_min_multiply_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE191_Integer_Underflow__char_min_multiply_68b_goodG2BSink(); +void CWE191_Integer_Underflow__char_min_multiply_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_min_multiply_68_goodG2BData = data; + CWE191_Integer_Underflow__char_min_multiply_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_multiply_68_goodB2GData = data; + CWE191_Integer_Underflow__char_min_multiply_68b_goodB2GSink(); +} + +void CWE191_Integer_Underflow__char_min_multiply_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_multiply_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_multiply_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_rand_multiply_53b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_multiply_53b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_rand_multiply_53c_badSink(int data); + +void CWE191_Integer_Underflow__int_rand_multiply_53b_badSink(int data) +{ + CWE191_Integer_Underflow__int_rand_multiply_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_multiply_53c_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_rand_multiply_53b_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_rand_multiply_53c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_multiply_53c_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_rand_multiply_53b_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_rand_multiply_53c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_fscanf_multiply_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_multiply_64b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_multiply_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * dataPtr = (char *)dataVoidPtr; + /* dereference dataPtr into data */ + char data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * dataPtr = (char *)dataVoidPtr; + /* dereference dataPtr into data */ + char data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * dataPtr = (char *)dataVoidPtr; + /* dereference dataPtr into data */ + char data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_fscanf_predec_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_predec_54d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_fscanf_predec_54e_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_predec_54d_badSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_fscanf_predec_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_predec_54e_goodG2BSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_predec_54d_goodG2BSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_fscanf_predec_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_predec_54e_goodB2GSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_predec_54d_goodB2GSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_fscanf_predec_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_postdec_21.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_postdec_21.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int64_t data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_rand_postdec_21_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int64_t data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int64_t data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int64_t data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE191_Integer_Underflow__int64_t_rand_postdec_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_postdec_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_postdec_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_postdec_09.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_postdec_09.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_postdec_09_bad() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_min_postdec_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_postdec_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_postdec_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_postdec_11.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_postdec_11.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_postdec_11_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_postdec_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_postdec_54b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_postdec_54b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fgets_postdec_54c_badSink(int data); + +void CWE191_Integer_Underflow__int_fgets_postdec_54b_badSink(int data) +{ + CWE191_Integer_Underflow__int_fgets_postdec_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_postdec_54c_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_fgets_postdec_54b_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_fgets_postdec_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_postdec_54c_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_fgets_postdec_54b_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_fgets_postdec_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_fscanf_predec_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_predec_54e.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_predec_54e_badSink(char data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_54e_goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_54e_goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_fscanf_sub_14.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_sub_14.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_sub_14_bad() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_sub_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_sub_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_sub_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_multiply_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_64b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_multiply_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_multiply_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_multiply_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_postdec_04.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_postdec_04.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_postdec_04_bad() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_TRUE) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + short data; + data = 0; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_min_postdec_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_postdec_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_postdec_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_predec_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_predec_66a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_predec_66b_badSink(char dataArray[]); + +void CWE191_Integer_Underflow__char_fscanf_predec_66_bad() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__char_fscanf_predec_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_66b_goodG2BSink(char dataArray[]); + +static void goodG2B() +{ + char data; + char dataArray[5]; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__char_fscanf_predec_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_66b_goodB2GSink(char dataArray[]); + +static void goodB2G() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + dataArray[2] = data; + CWE191_Integer_Underflow__char_fscanf_predec_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__char_fscanf_predec_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_predec_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_predec_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_sub_53d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_sub_53d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_sub_53d_badSink(short data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_sub_53d_goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_sub_53d_goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_fscanf_multiply_18.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_multiply_18.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_18_bad() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goto sink; +sink: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_predec_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_predec_54d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_predec_54e_badSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_predec_54d_badSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_predec_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_54e_goodG2BSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_predec_54d_goodG2BSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_predec_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_54e_goodB2GSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_predec_54d_goodB2GSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_predec_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_multiply_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_multiply_67b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__short_rand_multiply_67_structType +{ + short structFirst; +} CWE191_Integer_Underflow__short_rand_multiply_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_multiply_67b_badSink(CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct) +{ + short data = myStruct.structFirst; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_multiply_67b_goodG2BSink(CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct) +{ + short data = myStruct.structFirst; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_multiply_67b_goodB2GSink(CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct) +{ + short data = myStruct.structFirst; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_multiply_45.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_multiply_45.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static int64_t CWE191_Integer_Underflow__int64_t_rand_multiply_45_badData; +static int64_t CWE191_Integer_Underflow__int64_t_rand_multiply_45_goodG2BData; +static int64_t CWE191_Integer_Underflow__int64_t_rand_multiply_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_rand_multiply_45_badData; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +void CWE191_Integer_Underflow__int64_t_rand_multiply_45_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_multiply_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_rand_multiply_45_goodG2BData; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_rand_multiply_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_rand_multiply_45_goodB2GData; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_multiply_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__int64_t_rand_multiply_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_53b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_53b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53b_badSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_goodG2BSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53b_goodG2BSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_goodB2GSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53b_goodB2GSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fscanf_predec_54b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_predec_54b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fscanf_predec_54c_badSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_predec_54b_badSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_predec_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fscanf_predec_54c_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_predec_54b_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_predec_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fscanf_predec_54c_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_predec_54b_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_predec_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_sub_12.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_12.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_sub_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_postdec_16.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_postdec_16.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_postdec_16_bad() +{ + int64_t data; + data = 0LL; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + break; + } + while(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + break; + } +} + +void CWE191_Integer_Underflow__int64_t_rand_postdec_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_postdec_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_postdec_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_multiply_13.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_multiply_13_bad() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_multiply_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_predec_22a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_predec_22a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-22a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +int CWE191_Integer_Underflow__short_rand_predec_22_badGlobal = 0; + +void CWE191_Integer_Underflow__short_rand_predec_22_badSink(short data); + +void CWE191_Integer_Underflow__short_rand_predec_22_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE191_Integer_Underflow__short_rand_predec_22_badGlobal = 1; /* true */ + CWE191_Integer_Underflow__short_rand_predec_22_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +int CWE191_Integer_Underflow__short_rand_predec_22_goodB2G1Global = 0; +int CWE191_Integer_Underflow__short_rand_predec_22_goodB2G2Global = 0; +int CWE191_Integer_Underflow__short_rand_predec_22_goodG2BGlobal = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__short_rand_predec_22_goodB2G1Sink(short data); + +static void goodB2G1() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE191_Integer_Underflow__short_rand_predec_22_goodB2G1Global = 0; /* false */ + CWE191_Integer_Underflow__short_rand_predec_22_goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__short_rand_predec_22_goodB2G2Sink(short data); + +static void goodB2G2() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + CWE191_Integer_Underflow__short_rand_predec_22_goodB2G2Global = 1; /* true */ + CWE191_Integer_Underflow__short_rand_predec_22_goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__short_rand_predec_22_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__short_rand_predec_22_goodG2BGlobal = 1; /* true */ + CWE191_Integer_Underflow__short_rand_predec_22_goodG2BSink(data); +} + +void CWE191_Integer_Underflow__short_rand_predec_22_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_predec_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_predec_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_sub_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_sub_52a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_min_sub_52b_badSink(int data); + +void CWE191_Integer_Underflow__int_min_sub_52_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + CWE191_Integer_Underflow__int_min_sub_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_sub_52b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_min_sub_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_sub_52b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + CWE191_Integer_Underflow__int_min_sub_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_min_sub_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_sub_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_sub_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_06.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_06.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_06_bad() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_predec_07.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_predec_07.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-07.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + any other value so a tool should be able to identify that reads of + this will always give its initialized value. */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_predec_07_bad() +{ + short data; + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticFive==5 to staticFive!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(staticFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(staticFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_min_predec_07_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_predec_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_predec_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_multiply_09.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_multiply_09.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_multiply_09_bad() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(GLOBAL_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(GLOBAL_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_multiply_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_multiply_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_multiply_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_multiply_09.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_multiply_09.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_multiply_09_bad() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(GLOBAL_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char data; + data = ' '; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_fscanf_multiply_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_multiply_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_multiply_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_min_predec_68a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_predec_68a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +unsigned int CWE191_Integer_Underflow__unsigned_int_min_predec_68_badData; +unsigned int CWE191_Integer_Underflow__unsigned_int_min_predec_68_goodG2BData; +unsigned int CWE191_Integer_Underflow__unsigned_int_min_predec_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_min_predec_68b_badSink(); + +void CWE191_Integer_Underflow__unsigned_int_min_predec_68_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + CWE191_Integer_Underflow__unsigned_int_min_predec_68_badData = data; + CWE191_Integer_Underflow__unsigned_int_min_predec_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE191_Integer_Underflow__unsigned_int_min_predec_68b_goodG2BSink(); +void CWE191_Integer_Underflow__unsigned_int_min_predec_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__unsigned_int_min_predec_68_goodG2BData = data; + CWE191_Integer_Underflow__unsigned_int_min_predec_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + CWE191_Integer_Underflow__unsigned_int_min_predec_68_goodB2GData = data; + CWE191_Integer_Underflow__unsigned_int_min_predec_68b_goodB2GSink(); +} + +void CWE191_Integer_Underflow__unsigned_int_min_predec_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_min_predec_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_min_predec_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_multiply_67a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_multiply_67a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef struct _CWE191_Integer_Underflow__int_fgets_multiply_67_structType +{ + int structFirst; +} CWE191_Integer_Underflow__int_fgets_multiply_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fgets_multiply_67b_badSink(CWE191_Integer_Underflow__int_fgets_multiply_67_structType myStruct); + +void CWE191_Integer_Underflow__int_fgets_multiply_67_bad() +{ + int data; + CWE191_Integer_Underflow__int_fgets_multiply_67_structType myStruct; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_fgets_multiply_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_multiply_67b_goodG2BSink(CWE191_Integer_Underflow__int_fgets_multiply_67_structType myStruct); + +static void goodG2B() +{ + int data; + CWE191_Integer_Underflow__int_fgets_multiply_67_structType myStruct; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_fgets_multiply_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_multiply_67b_goodB2GSink(CWE191_Integer_Underflow__int_fgets_multiply_67_structType myStruct); + +static void goodB2G() +{ + int data; + CWE191_Integer_Underflow__int_fgets_multiply_67_structType myStruct; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_fgets_multiply_67b_goodB2GSink(myStruct); +} + +void CWE191_Integer_Underflow__int_fgets_multiply_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_multiply_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_multiply_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_listen_socket_postdec_05.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_postdec_05.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_postdec_05_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_listen_socket_postdec_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_postdec_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_postdec_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_predec_68a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_predec_68a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +int64_t CWE191_Integer_Underflow__int64_t_rand_predec_68_badData; +int64_t CWE191_Integer_Underflow__int64_t_rand_predec_68_goodG2BData; +int64_t CWE191_Integer_Underflow__int64_t_rand_predec_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_rand_predec_68b_badSink(); + +void CWE191_Integer_Underflow__int64_t_rand_predec_68_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_predec_68_badData = data; + CWE191_Integer_Underflow__int64_t_rand_predec_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE191_Integer_Underflow__int64_t_rand_predec_68b_goodG2BSink(); +void CWE191_Integer_Underflow__int64_t_rand_predec_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_rand_predec_68_goodG2BData = data; + CWE191_Integer_Underflow__int64_t_rand_predec_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_predec_68_goodB2GData = data; + CWE191_Integer_Underflow__int64_t_rand_predec_68b_goodB2GSink(); +} + +void CWE191_Integer_Underflow__int64_t_rand_predec_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_postdec_12.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_12.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_postdec_12_bad() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + else + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_postdec_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_postdec_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_postdec_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_predec_02.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_02.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_predec_02_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_listen_socket_predec_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_postdec_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_postdec_67b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__char_fscanf_postdec_67_structType +{ + char structFirst; +} CWE191_Integer_Underflow__char_fscanf_postdec_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_postdec_67b_badSink(CWE191_Integer_Underflow__char_fscanf_postdec_67_structType myStruct) +{ + char data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_postdec_67b_goodG2BSink(CWE191_Integer_Underflow__char_fscanf_postdec_67_structType myStruct) +{ + char data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_postdec_67b_goodB2GSink(CWE191_Integer_Underflow__char_fscanf_postdec_67_structType myStruct) +{ + char data = myStruct.structFirst; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_min_predec_54c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_predec_54c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_min_predec_54d_badSink(char data); + +void CWE191_Integer_Underflow__char_min_predec_54c_badSink(char data) +{ + CWE191_Integer_Underflow__char_min_predec_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_predec_54d_goodG2BSink(char data); + +void CWE191_Integer_Underflow__char_min_predec_54c_goodG2BSink(char data) +{ + CWE191_Integer_Underflow__char_min_predec_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_predec_54d_goodB2GSink(char data); + +void CWE191_Integer_Underflow__char_min_predec_54c_goodB2GSink(char data) +{ + CWE191_Integer_Underflow__char_min_predec_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_sub_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_65a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_sub_65b_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_sub_65_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_connect_socket_sub_65b_badSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_65b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_connect_socket_sub_65b_goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_65b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_connect_socket_sub_65b_goodB2GSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + funcPtr(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_13.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_13_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_postdec_68a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_postdec_68a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +int CWE191_Integer_Underflow__int_min_postdec_68_badData; +int CWE191_Integer_Underflow__int_min_postdec_68_goodG2BData; +int CWE191_Integer_Underflow__int_min_postdec_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_min_postdec_68b_badSink(); + +void CWE191_Integer_Underflow__int_min_postdec_68_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + CWE191_Integer_Underflow__int_min_postdec_68_badData = data; + CWE191_Integer_Underflow__int_min_postdec_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE191_Integer_Underflow__int_min_postdec_68b_goodG2BSink(); +void CWE191_Integer_Underflow__int_min_postdec_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_min_postdec_68_goodG2BData = data; + CWE191_Integer_Underflow__int_min_postdec_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + CWE191_Integer_Underflow__int_min_postdec_68_goodB2GData = data; + CWE191_Integer_Underflow__int_min_postdec_68b_goodB2GSink(); +} + +void CWE191_Integer_Underflow__int_min_postdec_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_postdec_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_postdec_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fscanf_predec_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_predec_22b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__int_fscanf_predec_22_badGlobal; + +void CWE191_Integer_Underflow__int_fscanf_predec_22_badSink(int data) +{ + if(CWE191_Integer_Underflow__int_fscanf_predec_22_badGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__int_fscanf_predec_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__int_fscanf_predec_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__int_fscanf_predec_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__int_fscanf_predec_22_goodB2G1Sink(int data) +{ + if(CWE191_Integer_Underflow__int_fscanf_predec_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__int_fscanf_predec_22_goodB2G2Sink(int data) +{ + if(CWE191_Integer_Underflow__int_fscanf_predec_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__int_fscanf_predec_22_goodG2BSink(int data) +{ + if(CWE191_Integer_Underflow__int_fscanf_predec_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_sub_67a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_sub_67a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__int_rand_sub_67_structType +{ + int structFirst; +} CWE191_Integer_Underflow__int_rand_sub_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_rand_sub_67b_badSink(CWE191_Integer_Underflow__int_rand_sub_67_structType myStruct); + +void CWE191_Integer_Underflow__int_rand_sub_67_bad() +{ + int data; + CWE191_Integer_Underflow__int_rand_sub_67_structType myStruct; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_rand_sub_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_sub_67b_goodG2BSink(CWE191_Integer_Underflow__int_rand_sub_67_structType myStruct); + +static void goodG2B() +{ + int data; + CWE191_Integer_Underflow__int_rand_sub_67_structType myStruct; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_rand_sub_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_sub_67b_goodB2GSink(CWE191_Integer_Underflow__int_rand_sub_67_structType myStruct); + +static void goodB2G() +{ + int data; + CWE191_Integer_Underflow__int_rand_sub_67_structType myStruct; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__int_rand_sub_67b_goodB2GSink(myStruct); +} + +void CWE191_Integer_Underflow__int_rand_sub_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_rand_sub_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_rand_sub_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_sub_42.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_sub_42.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static int64_t badSource(int64_t data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + return data; +} + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_42_bad() +{ + int64_t data; + data = 0LL; + data = badSource(data); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static int64_t goodG2BSource(int64_t data) +{ + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + return data; +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static int64_t goodB2GSource(int64_t data) +{ + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + return data; +} + +static void goodB2G() +{ + int64_t data; + data = 0LL; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_predec_64a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_64a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_listen_socket_predec_64b_badSink(void * dataVoidPtr); + +void CWE191_Integer_Underflow__int_listen_socket_predec_64_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_listen_socket_predec_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_listen_socket_predec_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_listen_socket_predec_64b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__int_listen_socket_predec_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_rand_sub_54a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_sub_54a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_rand_sub_54b_badSink(int data); + +void CWE191_Integer_Underflow__int_rand_sub_54_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + CWE191_Integer_Underflow__int_rand_sub_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_sub_54b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_rand_sub_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_sub_54b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + CWE191_Integer_Underflow__int_rand_sub_54b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_rand_sub_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_rand_sub_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_rand_sub_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_postdec_18.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_postdec_18.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_postdec_18_bad() +{ + char data; + data = ' '; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + char data; + data = ' '; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + char data; + data = ' '; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +void CWE191_Integer_Underflow__char_fscanf_postdec_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_postdec_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_postdec_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_postdec_32.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_postdec_32.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_postdec_32_bad() +{ + short data; + short *dataPtr1 = &data; + short *dataPtr2 = &data; + data = 0; + { + short data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + *dataPtr1 = data; + } + { + short data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + short data; + short *dataPtr1 = &data; + short *dataPtr2 = &data; + data = 0; + { + short data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + *dataPtr1 = data; + } + { + short data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + short data; + short *dataPtr1 = &data; + short *dataPtr2 = &data; + data = 0; + { + short data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + *dataPtr1 = data; + } + { + short data = *dataPtr2; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__short_rand_postdec_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_postdec_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_postdec_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-22a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +int CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_badGlobal = 0; + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_badGlobal = 1; /* true */ + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +int CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodB2G1Global = 0; +int CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodB2G2Global = 0; +int CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodG2BGlobal = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodB2G1Sink(unsigned int data); + +static void goodB2G1() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodB2G1Global = 0; /* false */ + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodB2G2Sink(unsigned int data); + +static void goodB2G2() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodB2G2Global = 1; /* true */ + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodG2BGlobal = 1; /* true */ + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_goodG2BSink(data); +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_sub_12.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_sub_12.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_sub_12_bad() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + else + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_sub_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_sub_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_sub_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_sub_42.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_sub_42.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static char badSource(char data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + return data; +} + +void CWE191_Integer_Underflow__char_rand_sub_42_bad() +{ + char data; + data = ' '; + data = badSource(data); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static char goodG2BSource(char data) +{ + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + return data; +} + +static void goodG2B() +{ + char data; + data = ' '; + data = goodG2BSource(data); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static char goodB2GSource(char data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + return data; +} + +static void goodB2G() +{ + char data; + data = ' '; + data = goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +void CWE191_Integer_Underflow__char_rand_sub_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_sub_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_sub_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_17.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_17.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_17_bad() +{ + int i,j; + unsigned int data; + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + unsigned int data; + data = 0; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + unsigned int data; + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_sub_54b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_sub_54b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_rand_sub_54c_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_rand_sub_54b_badSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_rand_sub_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_54c_goodG2BSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_rand_sub_54b_goodG2BSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_rand_sub_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_sub_54c_goodB2GSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_rand_sub_54b_goodB2GSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_rand_sub_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_predec_03.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_03.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_predec_03_bad() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(5==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_predec_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_predec_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_predec_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_postdec_52b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_postdec_52b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_rand_postdec_52c_badSink(short data); + +void CWE191_Integer_Underflow__short_rand_postdec_52b_badSink(short data) +{ + CWE191_Integer_Underflow__short_rand_postdec_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_postdec_52c_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_rand_postdec_52b_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_rand_postdec_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_postdec_52c_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_rand_postdec_52b_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_rand_postdec_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_postdec_51b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_postdec_51b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_postdec_51b_badSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_postdec_51b_goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_postdec_51b_goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_17.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_17.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_17_bad() +{ + int i,j; + int64_t data; + data = 0LL; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int64_t data; + data = 0LL; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int64_t data; + data = 0LL; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_multiply_12.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_12.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_multiply_12_bad() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + else + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(globalReturnsTrueOrFalse()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_multiply_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fscanf_sub_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_sub_22b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__int_fscanf_sub_22_badGlobal; + +void CWE191_Integer_Underflow__int_fscanf_sub_22_badSink(int data) +{ + if(CWE191_Integer_Underflow__int_fscanf_sub_22_badGlobal) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__int_fscanf_sub_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__int_fscanf_sub_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__int_fscanf_sub_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__int_fscanf_sub_22_goodB2G1Sink(int data) +{ + if(CWE191_Integer_Underflow__int_fscanf_sub_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__int_fscanf_sub_22_goodB2G2Sink(int data) +{ + if(CWE191_Integer_Underflow__int_fscanf_sub_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__int_fscanf_sub_22_goodG2BSink(int data) +{ + if(CWE191_Integer_Underflow__int_fscanf_sub_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_min_predec_09.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_predec_09.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_min_predec_09_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_min_predec_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_predec_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_predec_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_sub_09.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_sub_09.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_sub_09_bad() +{ + short data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + short data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + short data; + data = 0; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_sub_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_sub_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_sub_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_postdec_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_postdec_63b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_postdec_63b_badSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_postdec_63b_goodG2BSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_postdec_63b_goodB2GSink(char * dataPtr) +{ + char data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_sub_11.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_sub_11.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_sub_11_bad() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + short data; + data = 0; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_rand_sub_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_sub_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_sub_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_predec_67a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_predec_67a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__char_fscanf_predec_67_structType +{ + char structFirst; +} CWE191_Integer_Underflow__char_fscanf_predec_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_predec_67b_badSink(CWE191_Integer_Underflow__char_fscanf_predec_67_structType myStruct); + +void CWE191_Integer_Underflow__char_fscanf_predec_67_bad() +{ + char data; + CWE191_Integer_Underflow__char_fscanf_predec_67_structType myStruct; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_fscanf_predec_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_67b_goodG2BSink(CWE191_Integer_Underflow__char_fscanf_predec_67_structType myStruct); + +static void goodG2B() +{ + char data; + CWE191_Integer_Underflow__char_fscanf_predec_67_structType myStruct; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_fscanf_predec_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_predec_67b_goodB2GSink(CWE191_Integer_Underflow__char_fscanf_predec_67_structType myStruct); + +static void goodB2G() +{ + char data; + CWE191_Integer_Underflow__char_fscanf_predec_67_structType myStruct; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_fscanf_predec_67b_goodB2GSink(myStruct); +} + +void CWE191_Integer_Underflow__char_fscanf_predec_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_predec_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_predec_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_sub_01.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_sub_01.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_min_sub_01_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +void CWE191_Integer_Underflow__int_min_sub_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_sub_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_sub_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_sub_44.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_sub_44.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_44_bad() +{ + int64_t data; + /* define a function pointer */ + void (*funcPtr) (int64_t) = badSink; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +static void goodG2B() +{ + int64_t data; + void (*funcPtr) (int64_t) = goodG2BSink; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +static void goodB2G() +{ + int64_t data; + void (*funcPtr) (int64_t) = goodB2GSink; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + funcPtr(data); +} + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_predec_15.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_predec_15.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_predec_15_bad() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE191_Integer_Underflow__int_connect_socket_predec_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_multiply_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_multiply_61a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int64_t CWE191_Integer_Underflow__int64_t_fscanf_multiply_61b_badSource(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_61_bad() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_fscanf_multiply_61b_badSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int64_t CWE191_Integer_Underflow__int64_t_fscanf_multiply_61b_goodG2BSource(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_fscanf_multiply_61b_goodG2BSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int64_t CWE191_Integer_Underflow__int64_t_fscanf_multiply_61b_goodB2GSource(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_fscanf_multiply_61b_goodB2GSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_predec_45.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_predec_45.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +static int CWE191_Integer_Underflow__int_fgets_predec_45_badData; +static int CWE191_Integer_Underflow__int_fgets_predec_45_goodG2BData; +static int CWE191_Integer_Underflow__int_fgets_predec_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int data = CWE191_Integer_Underflow__int_fgets_predec_45_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_fgets_predec_45_bad() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE191_Integer_Underflow__int_fgets_predec_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int data = CWE191_Integer_Underflow__int_fgets_predec_45_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_fgets_predec_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int data = CWE191_Integer_Underflow__int_fgets_predec_45_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE191_Integer_Underflow__int_fgets_predec_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__int_fgets_predec_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_predec_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_predec_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_multiply_17.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_17.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_multiply_17_bad() +{ + int i,j; + int64_t data; + data = 0LL; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + for(j = 0; j < 1; j++) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int64_t data; + data = 0LL; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + for(k = 0; k < 1; k++) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int64_t data; + data = 0LL; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + for(j = 0; j < 1; j++) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_multiply_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_postdec_53d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_postdec_53d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_53d_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_53d_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_53d_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_postdec_54a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_54a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_postdec_54b_badSink(char data); + +void CWE191_Integer_Underflow__char_rand_postdec_54_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_postdec_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_postdec_54b_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_rand_postdec_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_postdec_54b_goodB2GSink(char data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_postdec_54b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_rand_postdec_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_postdec_64a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_64a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_postdec_64b_badSink(void * dataVoidPtr); + +void CWE191_Integer_Underflow__char_rand_postdec_64_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_postdec_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_postdec_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_rand_postdec_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_postdec_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + CWE191_Integer_Underflow__char_rand_postdec_64b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__char_rand_postdec_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_64a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_64a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_64b_badSink(void * dataVoidPtr); + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_64_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_fscanf_postdec_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_64b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_postdec_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_postdec_67b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef struct _CWE191_Integer_Underflow__int_fgets_postdec_67_structType +{ + int structFirst; +} CWE191_Integer_Underflow__int_fgets_postdec_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_postdec_67b_badSink(CWE191_Integer_Underflow__int_fgets_postdec_67_structType myStruct) +{ + int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_postdec_67b_goodG2BSink(CWE191_Integer_Underflow__int_fgets_postdec_67_structType myStruct) +{ + int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_postdec_67b_goodB2GSink(CWE191_Integer_Underflow__int_fgets_postdec_67_structType myStruct) +{ + int data = myStruct.structFirst; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_predec_41.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_41.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(char data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +void CWE191_Integer_Underflow__char_rand_predec_41_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_rand_predec_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_predec_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_predec_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_predec_12.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_predec_12.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_predec_12_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + else + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrueOrFalse()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalReturnsTrueOrFalse()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } + else + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_predec_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_66a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_66b_badSink(unsigned int dataArray[]); + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_66_bad() +{ + unsigned int data; + unsigned int dataArray[5]; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__unsigned_int_rand_sub_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_66b_goodG2BSink(unsigned int dataArray[]); + +static void goodG2B() +{ + unsigned int data; + unsigned int dataArray[5]; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__unsigned_int_rand_sub_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_66b_goodB2GSink(unsigned int dataArray[]); + +static void goodB2G() +{ + unsigned int data; + unsigned int dataArray[5]; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + dataArray[2] = data; + CWE191_Integer_Underflow__unsigned_int_rand_sub_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_predec_68b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_predec_68b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern char CWE191_Integer_Underflow__char_min_predec_68_badData; +extern char CWE191_Integer_Underflow__char_min_predec_68_goodG2BData; +extern char CWE191_Integer_Underflow__char_min_predec_68_goodB2GData; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_predec_68b_badSink() +{ + char data = CWE191_Integer_Underflow__char_min_predec_68_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_predec_68b_goodG2BSink() +{ + char data = CWE191_Integer_Underflow__char_min_predec_68_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_predec_68b_goodB2GSink() +{ + char data = CWE191_Integer_Underflow__char_min_predec_68_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_listen_socket_sub_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_sub_66a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_listen_socket_sub_66b_badSink(int dataArray[]); + +void CWE191_Integer_Underflow__int_listen_socket_sub_66_bad() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__int_listen_socket_sub_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_sub_66b_goodG2BSink(int dataArray[]); + +static void goodG2B() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__int_listen_socket_sub_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_sub_66b_goodB2GSink(int dataArray[]); + +static void goodB2G() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + dataArray[2] = data; + CWE191_Integer_Underflow__int_listen_socket_sub_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__int_listen_socket_sub_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_sub_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_sub_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_postdec_54c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_postdec_54c.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_listen_socket_postdec_54d_badSink(int data); + +void CWE191_Integer_Underflow__int_listen_socket_postdec_54c_badSink(int data) +{ + CWE191_Integer_Underflow__int_listen_socket_postdec_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_postdec_54d_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_listen_socket_postdec_54c_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_listen_socket_postdec_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_postdec_54d_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_listen_socket_postdec_54c_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_listen_socket_postdec_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_sub_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_sub_54d.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_rand_sub_54e_badSink(int data); + +void CWE191_Integer_Underflow__int_rand_sub_54d_badSink(int data) +{ + CWE191_Integer_Underflow__int_rand_sub_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_sub_54e_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_rand_sub_54d_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_rand_sub_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_sub_54e_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_rand_sub_54d_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_rand_sub_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_fscanf_multiply_52b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_multiply_52b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_multiply_52c_badSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_multiply_52b_badSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_multiply_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_52c_goodG2BSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_multiply_52b_goodG2BSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_multiply_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_52c_goodB2GSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_multiply_52b_goodB2GSink(char data) +{ + CWE191_Integer_Underflow__char_fscanf_multiply_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_predec_44.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_predec_44.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +void CWE191_Integer_Underflow__int64_t_rand_predec_44_bad() +{ + int64_t data; + /* define a function pointer */ + void (*funcPtr) (int64_t) = badSink; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +static void goodG2B() +{ + int64_t data; + void (*funcPtr) (int64_t) = goodG2BSink; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int64_t data; + void (*funcPtr) (int64_t) = goodB2GSink; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + funcPtr(data); +} + +void CWE191_Integer_Underflow__int64_t_rand_predec_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_sub_02.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_sub_02.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_sub_02_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(1) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_fgets_sub_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_sub_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_sub_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_postdec_45.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_postdec_45.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static short CWE191_Integer_Underflow__short_fscanf_postdec_45_badData; +static short CWE191_Integer_Underflow__short_fscanf_postdec_45_goodG2BData; +static short CWE191_Integer_Underflow__short_fscanf_postdec_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + short data = CWE191_Integer_Underflow__short_fscanf_postdec_45_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__short_fscanf_postdec_45_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE191_Integer_Underflow__short_fscanf_postdec_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + short data = CWE191_Integer_Underflow__short_fscanf_postdec_45_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__short_fscanf_postdec_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + short data = CWE191_Integer_Underflow__short_fscanf_postdec_45_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE191_Integer_Underflow__short_fscanf_postdec_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__short_fscanf_postdec_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_postdec_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_postdec_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_predec_21.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_predec_21.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(char data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_min_predec_21_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(char data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(char data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(char data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE191_Integer_Underflow__char_min_predec_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_predec_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_predec_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_predec_09.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_predec_09.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_09_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(GLOBAL_CONST_TRUE) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_predec_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_predec_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_multiply_34.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_multiply_34.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef union +{ + int unionFirst; + int unionSecond; +} CWE191_Integer_Underflow__int_connect_socket_multiply_34_unionType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_multiply_34_bad() +{ + int data; + CWE191_Integer_Underflow__int_connect_socket_multiply_34_unionType myUnion; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + CWE191_Integer_Underflow__int_connect_socket_multiply_34_unionType myUnion; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + CWE191_Integer_Underflow__int_connect_socket_multiply_34_unionType myUnion; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + myUnion.unionFirst = data; + { + int data = myUnion.unionSecond; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_multiply_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_sub_18.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_sub_18.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_min_sub_18_bad() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + goto sink; +sink: + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_min_sub_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_sub_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_sub_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_multiply_05.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_multiply_05.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_multiply_05_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_listen_socket_multiply_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fscanf_predec_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_predec_61a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE191_Integer_Underflow__int_fscanf_predec_61b_badSource(int data); + +void CWE191_Integer_Underflow__int_fscanf_predec_61_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fscanf_predec_61b_badSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE191_Integer_Underflow__int_fscanf_predec_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fscanf_predec_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE191_Integer_Underflow__int_fscanf_predec_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fscanf_predec_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__int_fscanf_predec_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_predec_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_predec_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_multiply_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_multiply_52a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_min_multiply_52b_badSink(int data); + +void CWE191_Integer_Underflow__int_min_multiply_52_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + CWE191_Integer_Underflow__int_min_multiply_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_multiply_52b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_min_multiply_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_multiply_52b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + CWE191_Integer_Underflow__int_min_multiply_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_min_multiply_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_multiply_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_multiply_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_predec_07.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_predec_07.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-07.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The variable below is not declared ""const"", but is never assigned + any other value so a tool should be able to identify that reads of + this will always give its initialized value. */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_predec_07_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticFive==5 to staticFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_predec_07_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_predec_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_sub_53d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_sub_53d.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_sub_53d_badSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_sub_53d_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_sub_53d_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_fscanf_multiply_54c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_54c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_fscanf_multiply_54d_badSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_54c_badSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_multiply_54d_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_54c_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_multiply_54d_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_54c_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_sub_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_sub_66a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_min_sub_66b_badSink(short dataArray[]); + +void CWE191_Integer_Underflow__short_min_sub_66_bad() +{ + short data; + short dataArray[5]; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__short_min_sub_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_sub_66b_goodG2BSink(short dataArray[]); + +static void goodG2B() +{ + short data; + short dataArray[5]; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__short_min_sub_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_sub_66b_goodB2GSink(short dataArray[]); + +static void goodB2G() +{ + short data; + short dataArray[5]; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + dataArray[2] = data; + CWE191_Integer_Underflow__short_min_sub_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__short_min_sub_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_sub_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_sub_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_sub_51a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_51a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-51a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_sub_51b_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_sub_51_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_connect_socket_sub_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_51b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_connect_socket_sub_51b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_51b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_connect_socket_sub_51b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_51_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_sub_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_sub_54d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_sub_54e_badSink(char data); + +void CWE191_Integer_Underflow__char_rand_sub_54d_badSink(char data) +{ + CWE191_Integer_Underflow__char_rand_sub_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_sub_54e_goodG2BSink(char data); + +void CWE191_Integer_Underflow__char_rand_sub_54d_goodG2BSink(char data) +{ + CWE191_Integer_Underflow__char_rand_sub_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_sub_54e_goodB2GSink(char data); + +void CWE191_Integer_Underflow__char_rand_sub_54d_goodB2GSink(char data) +{ + CWE191_Integer_Underflow__char_rand_sub_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_32.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_32.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_32_bad() +{ + unsigned int data; + unsigned int *dataPtr1 = &data; + unsigned int *dataPtr2 = &data; + data = 0; + { + unsigned int data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + *dataPtr1 = data; + } + { + unsigned int data = *dataPtr2; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + unsigned int *dataPtr1 = &data; + unsigned int *dataPtr2 = &data; + data = 0; + { + unsigned int data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + *dataPtr1 = data; + } + { + unsigned int data = *dataPtr2; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + unsigned int *dataPtr1 = &data; + unsigned int *dataPtr2 = &data; + data = 0; + { + unsigned int data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + *dataPtr1 = data; + } + { + unsigned int data = *dataPtr2; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_sub_06.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_sub_06.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_06_bad() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_sub_14.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_sub_14.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_14_bad() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fscanf_postdec_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_postdec_52a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fscanf_postdec_52b_badSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_postdec_52_bad() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE191_Integer_Underflow__int_fscanf_postdec_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fscanf_postdec_52b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_fscanf_postdec_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fscanf_postdec_52b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + CWE191_Integer_Underflow__int_fscanf_postdec_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_fscanf_postdec_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_postdec_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_postdec_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_sub_34.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_sub_34.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +typedef union +{ + int64_t unionFirst; + int64_t unionSecond; +} CWE191_Integer_Underflow__int64_t_min_sub_34_unionType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_sub_34_bad() +{ + int64_t data; + CWE191_Integer_Underflow__int64_t_min_sub_34_unionType myUnion; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + CWE191_Integer_Underflow__int64_t_min_sub_34_unionType myUnion; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + CWE191_Integer_Underflow__int64_t_min_sub_34_unionType myUnion; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_sub_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_sub_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_sub_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_min_postdec_13.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_postdec_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_min_postdec_13_bad() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + } + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_min_postdec_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_min_postdec_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_min_postdec_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_16.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_16.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_16_bad() +{ + unsigned int data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + unsigned int data; + data = 0; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + break; + } + while(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + unsigned int data; + data = 0; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + break; + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_postdec_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_63b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_postdec_63b_badSink(int64_t * dataPtr) +{ + int64_t data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_63b_goodG2BSink(int64_t * dataPtr) +{ + int64_t data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_63b_goodB2GSink(int64_t * dataPtr) +{ + int64_t data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fgets_postdec_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_postdec_64b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_postdec_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_postdec_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_postdec_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_predec_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_63b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_predec_63b_badSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_predec_63b_goodG2BSink(char * dataPtr) +{ + char data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_predec_63b_goodB2GSink(char * dataPtr) +{ + char data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fgets_predec_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_predec_53c.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fgets_predec_53d_badSink(int data); + +void CWE191_Integer_Underflow__int_fgets_predec_53c_badSink(int data) +{ + CWE191_Integer_Underflow__int_fgets_predec_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_predec_53d_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_fgets_predec_53c_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_fgets_predec_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_predec_53d_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_fgets_predec_53c_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_fgets_predec_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fscanf_multiply_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_multiply_61a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE191_Integer_Underflow__int_fscanf_multiply_61b_badSource(int data); + +void CWE191_Integer_Underflow__int_fscanf_multiply_61_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fscanf_multiply_61b_badSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE191_Integer_Underflow__int_fscanf_multiply_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fscanf_multiply_61b_goodG2BSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE191_Integer_Underflow__int_fscanf_multiply_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fscanf_multiply_61b_goodB2GSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +void CWE191_Integer_Underflow__int_fscanf_multiply_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_multiply_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_multiply_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +unsigned int CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_badData; +unsigned int CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_goodG2BData; +unsigned int CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68b_badSink(); + +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_badData = data; + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68b_goodG2BSink(); +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_goodG2BData = data; + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_goodB2GData = data; + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68b_goodB2GSink(); +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54e_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54d_badSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54e_goodG2BSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54d_goodG2BSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54e_goodB2GSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54d_goodB2GSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_fscanf_sub_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_52c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_52c_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_52c_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_52c_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_65a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_65b_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_65_bad() +{ + unsigned int data; + /* define a function pointer */ + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_rand_sub_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_65b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_rand_sub_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_65b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_rand_sub_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + funcPtr(data); +} + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_67b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__unsigned_int_rand_sub_67_structType +{ + unsigned int structFirst; +} CWE191_Integer_Underflow__unsigned_int_rand_sub_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_67b_badSink(CWE191_Integer_Underflow__unsigned_int_rand_sub_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_67b_goodG2BSink(CWE191_Integer_Underflow__unsigned_int_rand_sub_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_67b_goodB2GSink(CWE191_Integer_Underflow__unsigned_int_rand_sub_67_structType myStruct) +{ + unsigned int data = myStruct.structFirst; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65_bad() +{ + unsigned int data; + /* define a function pointer */ + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + funcPtr(data); +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_multiply_63a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_multiply_63a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_rand_multiply_63b_badSink(int64_t * dataPtr); + +void CWE191_Integer_Underflow__int64_t_rand_multiply_63_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_multiply_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_multiply_63b_goodG2BSink(int64_t * data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_rand_multiply_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_multiply_63b_goodB2GSink(int64_t * data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_multiply_63b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__int64_t_rand_multiply_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_54a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_54a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_54b_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_54_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE191_Integer_Underflow__unsigned_int_rand_predec_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_54b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__unsigned_int_rand_predec_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_54b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE191_Integer_Underflow__unsigned_int_rand_predec_54b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_predec_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_predec_22b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__short_min_predec_22_badGlobal; + +void CWE191_Integer_Underflow__short_min_predec_22_badSink(short data) +{ + if(CWE191_Integer_Underflow__short_min_predec_22_badGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__short_min_predec_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__short_min_predec_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__short_min_predec_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__short_min_predec_22_goodB2G1Sink(short data) +{ + if(CWE191_Integer_Underflow__short_min_predec_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__short_min_predec_22_goodB2G2Sink(short data) +{ + if(CWE191_Integer_Underflow__short_min_predec_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__short_min_predec_22_goodG2BSink(short data) +{ + if(CWE191_Integer_Underflow__short_min_predec_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fgets_multiply_14.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_multiply_14.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_multiply_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_fgets_multiply_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_multiply_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_multiply_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_postdec_18.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_postdec_18.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_18_bad() +{ + unsigned int data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + unsigned int data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + unsigned int data; + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_postdec_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_postdec_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_postdec_14.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_postdec_14.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_postdec_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_listen_socket_postdec_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_postdec_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_postdec_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_sub_16.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_sub_16.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_sub_16_bad() +{ + int64_t data; + data = 0LL; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + break; + } + while(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + break; + } +} + +void CWE191_Integer_Underflow__int64_t_rand_sub_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_sub_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_sub_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_rand_multiply_32.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_multiply_32.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_multiply_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = 0; + { + int data = *dataPtr1; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + *dataPtr1 = data; + } + { + int data = *dataPtr2; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +void CWE191_Integer_Underflow__int_rand_multiply_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_rand_multiply_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_rand_multiply_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_sub_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_54d.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_sub_54e_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_sub_54d_badSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_sub_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_54e_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_sub_54d_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_sub_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_54e_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_sub_54d_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_sub_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_08.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_08.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_08_bad() +{ + unsigned int data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%u"", &data); + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_postdec_32.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_postdec_32.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_postdec_32_bad() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + *dataPtr1 = data; + } + { + char data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + *dataPtr1 = data; + } + { + char data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + char *dataPtr1 = &data; + char *dataPtr2 = &data; + data = ' '; + { + char data = *dataPtr1; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + *dataPtr1 = data; + } + { + char data = *dataPtr2; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__char_min_postdec_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_postdec_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_postdec_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_multiply_04.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_multiply_04.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_multiply_04_bad() +{ + char data; + data = ' '; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + char data; + data = ' '; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char data; + data = ' '; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_multiply_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_multiply_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_multiply_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_postdec_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_postdec_63b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_postdec_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_postdec_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_postdec_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_predec_54a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_predec_54a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_min_predec_54b_badSink(short data); + +void CWE191_Integer_Underflow__short_min_predec_54_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + CWE191_Integer_Underflow__short_min_predec_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_predec_54b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__short_min_predec_54b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_predec_54b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + CWE191_Integer_Underflow__short_min_predec_54b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__short_min_predec_54_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_predec_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_predec_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_54c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_54c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_54d_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_54c_badSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_fscanf_postdec_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_54d_goodG2BSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_54c_goodG2BSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_fscanf_postdec_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_54d_goodB2GSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_54c_goodB2GSink(int64_t data) +{ + CWE191_Integer_Underflow__int64_t_fscanf_postdec_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_min_sub_63a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_sub_63a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_min_sub_63b_badSink(char * dataPtr); + +void CWE191_Integer_Underflow__char_min_sub_63_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_sub_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_sub_63b_goodG2BSink(char * data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_min_sub_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_sub_63b_goodB2GSink(char * data); + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_sub_63b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__char_min_sub_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_sub_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_sub_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_postdec_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_postdec_61a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE191_Integer_Underflow__int_fgets_postdec_61b_badSource(int data); + +void CWE191_Integer_Underflow__int_fgets_postdec_61_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fgets_postdec_61b_badSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE191_Integer_Underflow__int_fgets_postdec_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fgets_postdec_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE191_Integer_Underflow__int_fgets_postdec_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fgets_postdec_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__int_fgets_postdec_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_postdec_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_postdec_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_rand_postdec_05.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_postdec_05.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_postdec_05_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(staticTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_rand_postdec_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_rand_postdec_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_rand_postdec_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_predec_14.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_predec_14.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_predec_14_bad() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_min_predec_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_predec_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_predec_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_sub_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_sub_64b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_sub_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_sub_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_sub_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_postdec_02.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_postdec_02.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_postdec_02_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_postdec_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_predec_08.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_predec_08.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_predec_08_bad() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + } + if(staticReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(staticReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_rand_predec_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_predec_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_postdec_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_postdec_52a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_rand_postdec_52b_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_rand_postdec_52_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_postdec_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_postdec_52b_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_rand_postdec_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_postdec_52b_goodB2GSink(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_postdec_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int64_t_rand_postdec_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_postdec_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_postdec_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_predec_68b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_predec_68b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern short CWE191_Integer_Underflow__short_min_predec_68_badData; +extern short CWE191_Integer_Underflow__short_min_predec_68_goodG2BData; +extern short CWE191_Integer_Underflow__short_min_predec_68_goodB2GData; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_predec_68b_badSink() +{ + short data = CWE191_Integer_Underflow__short_min_predec_68_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_predec_68b_goodG2BSink() +{ + short data = CWE191_Integer_Underflow__short_min_predec_68_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_predec_68b_goodB2GSink() +{ + short data = CWE191_Integer_Underflow__short_min_predec_68_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_sub_41.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_41.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +static void badSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_41_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_sub_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_sub_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_64b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + unsigned int * dataPtr = (unsigned int *)dataVoidPtr; + /* dereference dataPtr into data */ + unsigned int data = (*dataPtr); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fscanf_sub_18.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_sub_18.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fscanf_sub_18_bad() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + goto sink; +sink: + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_fscanf_sub_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_sub_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_sub_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_postdec_17.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_postdec_17.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_postdec_17_bad() +{ + int i,j; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + for(k = 0; k < 1; k++) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + data--; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int data; + /* Initialize data */ + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + for(j = 0; j < 1; j++) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_postdec_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_sub_51b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_sub_51b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_sub_51b_badSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_sub_51b_goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_sub_51b_goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_postdec_03.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_03.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_postdec_03_bad() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(5==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(5==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(5==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(5==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_postdec_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_multiply_17.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_multiply_17.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_multiply_17_bad() +{ + int i,j; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + for(j = 0; j < 1; j++) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int data; + /* Initialize data */ + data = 0; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + for(k = 0; k < 1; k++) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int data; + /* Initialize data */ + data = 0; + for(h = 0; h < 1; h++) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + for(j = 0; j < 1; j++) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_connect_socket_multiply_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_54e.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_54e_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_54e_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_postdec_54e_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_multiply_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_multiply_52c.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_multiply_52c_badSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_multiply_52c_goodG2BSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_multiply_52c_goodB2GSink(int data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fgets_predec_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_predec_52c.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_predec_52c_badSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_predec_52c_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_predec_52c_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_rand_predec_51b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_predec_51b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_predec_51b_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_predec_51b_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_predec_51b_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_postdec_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_22b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__char_rand_postdec_22_badGlobal; + +void CWE191_Integer_Underflow__char_rand_postdec_22_badSink(char data) +{ + if(CWE191_Integer_Underflow__char_rand_postdec_22_badGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__char_rand_postdec_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__char_rand_postdec_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__char_rand_postdec_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__char_rand_postdec_22_goodB2G1Sink(char data) +{ + if(CWE191_Integer_Underflow__char_rand_postdec_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__char_rand_postdec_22_goodB2G2Sink(char data) +{ + if(CWE191_Integer_Underflow__char_rand_postdec_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__char_rand_postdec_22_goodG2BSink(char data) +{ + if(CWE191_Integer_Underflow__char_rand_postdec_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_fscanf_multiply_13.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_multiply_13.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_13_bad() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(GLOBAL_CONST_FIVE==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_multiply_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_multiply_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_predec_53a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_predec_53a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_fscanf_predec_53b_badSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_predec_53_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE191_Integer_Underflow__short_fscanf_predec_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_predec_53b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__short_fscanf_predec_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_predec_53b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + CWE191_Integer_Underflow__short_fscanf_predec_53b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__short_fscanf_predec_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_predec_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_predec_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_multiply_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_multiply_54e.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_multiply_54e_badSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_multiply_54e_goodG2BSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_multiply_54e_goodB2GSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fgets_sub_06.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_sub_06.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_sub_06_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FIVE==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_FIVE==5) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_fgets_sub_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_sub_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_sub_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_multiply_14.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_multiply_14.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_multiply_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_listen_socket_multiply_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_multiply_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_53c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53d_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_badSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_sub_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53d_goodG2BSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_goodG2BSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_sub_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53d_goodB2GSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_53c_goodB2GSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_sub_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_multiply_66b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_multiply_66b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_multiply_66b_badSink(short dataArray[]) +{ + /* copy data out of dataArray */ + short data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_multiply_66b_goodG2BSink(short dataArray[]) +{ + short data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_multiply_66b_goodB2GSink(short dataArray[]) +{ + short data = dataArray[2]; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_fgets_sub_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_sub_52a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fgets_sub_52b_badSink(int data); + +void CWE191_Integer_Underflow__int_fgets_sub_52_bad() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE191_Integer_Underflow__int_fgets_sub_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_sub_52b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_fgets_sub_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_sub_52b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE191_Integer_Underflow__int_fgets_sub_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_fgets_sub_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_sub_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_sub_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_postdec_64a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_postdec_64a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_postdec_64b_badSink(void * dataVoidPtr); + +void CWE191_Integer_Underflow__int_connect_socket_postdec_64_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_connect_socket_postdec_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_postdec_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_connect_socket_postdec_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_postdec_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_connect_socket_postdec_64b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__int_connect_socket_postdec_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_postdec_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_15.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_15.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_15_bad() +{ + int64_t data; + data = 0LL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_postdec_07.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_07.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-07.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + any other value so a tool should be able to identify that reads of + this will always give its initialized value. */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_postdec_07_bad() +{ + char data; + data = ' '; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticFive==5 to staticFive!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(staticFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(staticFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(staticFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_postdec_07_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_predec_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_predec_61a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int64_t CWE191_Integer_Underflow__int64_t_min_predec_61b_badSource(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_predec_61_bad() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_predec_61b_badSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int64_t CWE191_Integer_Underflow__int64_t_min_predec_61b_goodG2BSource(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_predec_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int64_t CWE191_Integer_Underflow__int64_t_min_predec_61b_goodB2GSource(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_predec_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__int64_t_min_predec_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_predec_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_predec_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_sub_10.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_sub_10.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_sub_10_bad() +{ + short data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + short data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + short data; + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_rand_sub_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_sub_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_sub_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_predec_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_predec_66a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_min_predec_66b_badSink(int dataArray[]); + +void CWE191_Integer_Underflow__int_min_predec_66_bad() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__int_min_predec_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_predec_66b_goodG2BSink(int dataArray[]); + +static void goodG2B() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__int_min_predec_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_predec_66b_goodB2GSink(int dataArray[]); + +static void goodB2G() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* POTENTIAL FLAW: Use the minimum value for this type */ + data = INT_MIN; + dataArray[2] = data; + CWE191_Integer_Underflow__int_min_predec_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__int_min_predec_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_min_predec_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_min_predec_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_predec_01.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_predec_01.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fgets_predec_01_bad() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__int_fgets_predec_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_predec_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_predec_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_predec_14.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_predec_14.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_predec_14_bad() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + short data; + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_rand_predec_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_predec_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_predec_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_sub_44.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_sub_44.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +void CWE191_Integer_Underflow__char_min_sub_44_bad() +{ + char data; + /* define a function pointer */ + void (*funcPtr) (char) = badSink; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + void (*funcPtr) (char) = goodG2BSink; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +static void goodB2G() +{ + char data; + void (*funcPtr) (char) = goodB2GSink; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + funcPtr(data); +} + +void CWE191_Integer_Underflow__char_min_sub_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_sub_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_sub_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_44.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_44.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_44_bad() +{ + unsigned int data; + /* define a function pointer */ + void (*funcPtr) (unsigned int) = badSink; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +static void goodG2B() +{ + unsigned int data; + void (*funcPtr) (unsigned int) = goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + unsigned int data; + void (*funcPtr) (unsigned int) = goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + funcPtr(data); +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_postdec_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_postdec_54e.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_postdec_54e_badSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_postdec_54e_goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_postdec_54e_goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_min_multiply_41.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_multiply_41.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +void CWE191_Integer_Underflow__char_min_multiply_41_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < CHAR_MIN, this will underflow */ + char result = data * 2; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(char data) +{ + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (CHAR_MIN/2)) + { + char result = data * 2; + printHexCharLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + goodB2GSink(data); +} + +void CWE191_Integer_Underflow__char_min_multiply_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_multiply_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_multiply_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_61b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_61b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +unsigned int CWE191_Integer_Underflow__unsigned_int_rand_predec_61b_badSource(unsigned int data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +unsigned int CWE191_Integer_Underflow__unsigned_int_rand_predec_61b_goodG2BSource(unsigned int data) +{ + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + return data; +} + +/* goodB2G() uses the BadSource with the GoodSink */ +unsigned int CWE191_Integer_Underflow__unsigned_int_rand_predec_61b_goodB2GSource(unsigned int data) +{ + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + return data; +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_postdec_53a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_postdec_53a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_min_postdec_53b_badSink(short data); + +void CWE191_Integer_Underflow__short_min_postdec_53_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + CWE191_Integer_Underflow__short_min_postdec_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_postdec_53b_goodG2BSink(short data); + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__short_min_postdec_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_postdec_53b_goodB2GSink(short data); + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + CWE191_Integer_Underflow__short_min_postdec_53b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__short_min_postdec_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_postdec_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_postdec_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_predec_11.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_predec_11.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_fscanf_predec_11_bad() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char data; + data = ' '; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_fscanf_predec_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_predec_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_predec_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_multiply_05.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_05.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_multiply_05_bad() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(staticTrue) + { + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + short data; + data = 0; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(staticTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(staticTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_multiply_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_predec_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_predec_61a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE191_Integer_Underflow__int_fgets_predec_61b_badSource(int data); + +void CWE191_Integer_Underflow__int_fgets_predec_61_bad() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fgets_predec_61b_badSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE191_Integer_Underflow__int_fgets_predec_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fgets_predec_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE191_Integer_Underflow__int_fgets_predec_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + data = CWE191_Integer_Underflow__int_fgets_predec_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__int_fgets_predec_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_predec_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_predec_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_sub_22b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_sub_22b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-22b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +extern int CWE191_Integer_Underflow__char_rand_sub_22_badGlobal; + +void CWE191_Integer_Underflow__char_rand_sub_22_badSink(char data) +{ + if(CWE191_Integer_Underflow__char_rand_sub_22_badGlobal) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +extern int CWE191_Integer_Underflow__char_rand_sub_22_goodB2G1Global; +extern int CWE191_Integer_Underflow__char_rand_sub_22_goodB2G2Global; +extern int CWE191_Integer_Underflow__char_rand_sub_22_goodG2BGlobal; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__char_rand_sub_22_goodB2G1Sink(char data) +{ + if(CWE191_Integer_Underflow__char_rand_sub_22_goodB2G1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__char_rand_sub_22_goodB2G2Sink(char data) +{ + if(CWE191_Integer_Underflow__char_rand_sub_22_goodB2G2Global) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__char_rand_sub_22_goodG2BSink(char data) +{ + if(CWE191_Integer_Underflow__char_rand_sub_22_goodG2BGlobal) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_rand_multiply_67a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_multiply_67a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__short_rand_multiply_67_structType +{ + short structFirst; +} CWE191_Integer_Underflow__short_rand_multiply_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_rand_multiply_67b_badSink(CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct); + +void CWE191_Integer_Underflow__short_rand_multiply_67_bad() +{ + short data; + CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__short_rand_multiply_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_multiply_67b_goodG2BSink(CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct); + +static void goodG2B() +{ + short data; + CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + myStruct.structFirst = data; + CWE191_Integer_Underflow__short_rand_multiply_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_multiply_67b_goodB2GSink(CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct); + +static void goodB2G() +{ + short data; + CWE191_Integer_Underflow__short_rand_multiply_67_structType myStruct; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__short_rand_multiply_67b_goodB2GSink(myStruct); +} + +void CWE191_Integer_Underflow__short_rand_multiply_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_multiply_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_multiply_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_sub_63b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_63b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_sub_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + int result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_multiply_02.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_multiply_02.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_multiply_02_bad() +{ + short data; + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + short data; + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(1) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + short data; + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_min_multiply_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_multiply_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_multiply_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_postdec_54c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_postdec_54c.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_min_postdec_54d_badSink(int data); + +void CWE191_Integer_Underflow__int_min_postdec_54c_badSink(int data) +{ + CWE191_Integer_Underflow__int_min_postdec_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_postdec_54d_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_min_postdec_54c_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_min_postdec_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_postdec_54d_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_min_postdec_54c_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_min_postdec_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_listen_socket_predec_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_65a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_listen_socket_predec_65b_badSink(int data); + +void CWE191_Integer_Underflow__int_listen_socket_predec_65_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_listen_socket_predec_65b_badSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_65b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_listen_socket_predec_65b_goodG2BSink; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_65b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = CWE191_Integer_Underflow__int_listen_socket_predec_65b_goodB2GSink; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + funcPtr(data); +} + +void CWE191_Integer_Underflow__int_listen_socket_predec_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_postdec_54c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_postdec_54c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_54d_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_54c_badSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_postdec_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_54d_goodG2BSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_54c_goodG2BSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_postdec_54d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_54d_goodB2GSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_54c_goodB2GSink(unsigned int data) +{ + CWE191_Integer_Underflow__unsigned_int_rand_postdec_54d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_predec_18.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_predec_18.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_predec_18_bad() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__int_rand_predec_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_rand_predec_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_rand_predec_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fgets_multiply_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fgets_multiply_52a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fgets_multiply_52b_badSink(int data); + +void CWE191_Integer_Underflow__int_fgets_multiply_52_bad() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE191_Integer_Underflow__int_fgets_multiply_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fgets_multiply_52b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_fgets_multiply_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fgets_multiply_52b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE191_Integer_Underflow__int_fgets_multiply_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_fgets_multiply_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fgets_multiply_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fgets_multiply_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_predec_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_predec_52c.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_predec_52c_badSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_predec_52c_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_predec_52c_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_fscanf_sub_18.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_sub_18.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_18_bad() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + goto sink; +sink: + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_sub_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_sub_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_multiply_15.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_15.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_multiply_15_bad() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + short data; + data = 0; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + short data; + data = 0; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE191_Integer_Underflow__short_fscanf_multiply_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_postdec_16.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_postdec_16.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_postdec_16_bad() +{ + char data; + data = ' '; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + char data; + data = ' '; + while(1) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + break; + } + while(1) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + char data; + data = ' '; + while(1) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + while(1) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } + break; + } +} + +void CWE191_Integer_Underflow__char_rand_postdec_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_postdec_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_postdec_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_multiply_64a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_multiply_64a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int64_t_rand_multiply_64b_badSink(void * dataVoidPtr); + +void CWE191_Integer_Underflow__int64_t_rand_multiply_64_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_multiply_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_rand_multiply_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_rand_multiply_64b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_rand_multiply_64b_goodB2GSink(void * dataVoidPtr); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + CWE191_Integer_Underflow__int64_t_rand_multiply_64b_goodB2GSink(&data); +} + +void CWE191_Integer_Underflow__int64_t_rand_multiply_64_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_multiply_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_sub_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_sub_53c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_rand_sub_53d_badSink(short data); + +void CWE191_Integer_Underflow__short_rand_sub_53c_badSink(short data) +{ + CWE191_Integer_Underflow__short_rand_sub_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_rand_sub_53d_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_rand_sub_53c_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_rand_sub_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_rand_sub_53d_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_rand_sub_53c_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_rand_sub_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_connect_socket_multiply_53a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_multiply_53a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_53b_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_multiply_53_bad() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_connect_socket_multiply_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_53b_goodG2BSink(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int_connect_socket_multiply_53b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_multiply_53b_goodB2GSink(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE191_Integer_Underflow__int_connect_socket_multiply_53b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__int_connect_socket_multiply_53_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_connect_socket_multiply_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_predec_21.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_predec_21.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(short data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_predec_21_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(short data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(short data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(short data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } + } +} + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE191_Integer_Underflow__short_fscanf_predec_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_predec_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_predec_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_postdec_45.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_postdec_45.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static char CWE191_Integer_Underflow__char_min_postdec_45_badData; +static char CWE191_Integer_Underflow__char_min_postdec_45_goodG2BData; +static char CWE191_Integer_Underflow__char_min_postdec_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + char data = CWE191_Integer_Underflow__char_min_postdec_45_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +void CWE191_Integer_Underflow__char_min_postdec_45_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_postdec_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char data = CWE191_Integer_Underflow__char_min_postdec_45_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_min_postdec_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + char data = CWE191_Integer_Underflow__char_min_postdec_45_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + CWE191_Integer_Underflow__char_min_postdec_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__char_min_postdec_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_postdec_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_postdec_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_sub_45.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_sub_45.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static char CWE191_Integer_Underflow__char_fscanf_sub_45_badData; +static char CWE191_Integer_Underflow__char_fscanf_sub_45_goodG2BData; +static char CWE191_Integer_Underflow__char_fscanf_sub_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + char data = CWE191_Integer_Underflow__char_fscanf_sub_45_badData; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +void CWE191_Integer_Underflow__char_fscanf_sub_45_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_sub_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char data = CWE191_Integer_Underflow__char_fscanf_sub_45_goodG2BData; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_fscanf_sub_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + char data = CWE191_Integer_Underflow__char_fscanf_sub_45_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_sub_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__char_fscanf_sub_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_sub_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_sub_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_min_multiply_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_min_multiply_54d.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the minimum value for int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_min_multiply_54e_badSink(int data); + +void CWE191_Integer_Underflow__int_min_multiply_54d_badSink(int data) +{ + CWE191_Integer_Underflow__int_min_multiply_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_min_multiply_54e_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_min_multiply_54d_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_min_multiply_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_min_multiply_54e_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_min_multiply_54d_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_min_multiply_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_postdec_51b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_51b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_postdec_51b_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_51b_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_51b_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_61a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_61b_badSource(int64_t data); + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_61_bad() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_61b_badSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_61b_goodG2BSource(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_61b_goodB2GSource(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_multiply_22a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_multiply_22a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-22a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +int CWE191_Integer_Underflow__char_fscanf_multiply_22_badGlobal = 0; + +void CWE191_Integer_Underflow__char_fscanf_multiply_22_badSink(char data); + +void CWE191_Integer_Underflow__char_fscanf_multiply_22_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_multiply_22_badGlobal = 1; /* true */ + CWE191_Integer_Underflow__char_fscanf_multiply_22_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +int CWE191_Integer_Underflow__char_fscanf_multiply_22_goodB2G1Global = 0; +int CWE191_Integer_Underflow__char_fscanf_multiply_22_goodB2G2Global = 0; +int CWE191_Integer_Underflow__char_fscanf_multiply_22_goodG2BGlobal = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__char_fscanf_multiply_22_goodB2G1Sink(char data); + +static void goodB2G1() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_multiply_22_goodB2G1Global = 0; /* false */ + CWE191_Integer_Underflow__char_fscanf_multiply_22_goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__char_fscanf_multiply_22_goodB2G2Sink(char data); + +static void goodB2G2() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + CWE191_Integer_Underflow__char_fscanf_multiply_22_goodB2G2Global = 1; /* true */ + CWE191_Integer_Underflow__char_fscanf_multiply_22_goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__char_fscanf_multiply_22_goodG2BSink(char data); + +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__char_fscanf_multiply_22_goodG2BGlobal = 1; /* true */ + CWE191_Integer_Underflow__char_fscanf_multiply_22_goodG2BSink(data); +} + +void CWE191_Integer_Underflow__char_fscanf_multiply_22_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_multiply_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_multiply_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_sub_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_sub_67b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__short_fscanf_sub_67_structType +{ + short structFirst; +} CWE191_Integer_Underflow__short_fscanf_sub_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_sub_67b_badSink(CWE191_Integer_Underflow__short_fscanf_sub_67_structType myStruct) +{ + short data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_sub_67b_goodG2BSink(CWE191_Integer_Underflow__short_fscanf_sub_67_structType myStruct) +{ + short data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + short result = data - 1; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_sub_67b_goodB2GSink(CWE191_Integer_Underflow__short_fscanf_sub_67_structType myStruct) +{ + short data = myStruct.structFirst; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + short result = data - 1; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_fscanf_multiply_54b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_54b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__short_fscanf_multiply_54c_badSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_54b_badSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_multiply_54c_goodG2BSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_54b_goodG2BSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_54c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_multiply_54c_goodB2GSink(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_54b_goodB2GSink(short data) +{ + CWE191_Integer_Underflow__short_fscanf_multiply_54c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_multiply_34.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_34.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +typedef union +{ + int64_t unionFirst; + int64_t unionSecond; +} CWE191_Integer_Underflow__int64_t_min_multiply_34_unionType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_multiply_34_bad() +{ + int64_t data; + CWE191_Integer_Underflow__int64_t_min_multiply_34_unionType myUnion; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + CWE191_Integer_Underflow__int64_t_min_multiply_34_unionType myUnion; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + CWE191_Integer_Underflow__int64_t_min_multiply_34_unionType myUnion; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + myUnion.unionFirst = data; + { + int64_t data = myUnion.unionSecond; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_multiply_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_postdec_41.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_postdec_41.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__short_rand_postdec_41_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(short data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(short data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + goodB2GSink(data); +} + +void CWE191_Integer_Underflow__short_rand_postdec_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_postdec_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_postdec_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_predec_51b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_predec_51b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_predec_51b_badSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_predec_51b_goodG2BSink(int64_t data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_predec_51b_goodB2GSink(int64_t data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_min_postdec_52c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_postdec_52c.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_postdec_52c_badSink(char data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_postdec_52c_goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_postdec_52c_goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + data--; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_sub_53c.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_sub_53c.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_rand_sub_53d_badSink(int data); + +void CWE191_Integer_Underflow__int_rand_sub_53c_badSink(int data) +{ + CWE191_Integer_Underflow__int_rand_sub_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_sub_53d_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_rand_sub_53c_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_rand_sub_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_sub_53d_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_rand_sub_53c_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_rand_sub_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int64_t_min_predec_31.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_predec_31.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_predec_31_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + { + int64_t dataCopy = data; + int64_t data = dataCopy; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + { + int64_t dataCopy = data; + int64_t data = dataCopy; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + { + int64_t dataCopy = data; + int64_t data = dataCopy; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + --data; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_predec_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_predec_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_predec_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_14.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_14.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_14_bad() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_65b_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_fscanf_multiply_01.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_01.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_multiply_01_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%hd"", &data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_multiply_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_sub_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_sub_61a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int64_t CWE191_Integer_Underflow__int64_t_min_sub_61b_badSource(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_sub_61_bad() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_sub_61b_badSource(data); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int64_t CWE191_Integer_Underflow__int64_t_min_sub_61b_goodG2BSource(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_sub_61b_goodG2BSource(data); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int64_t CWE191_Integer_Underflow__int64_t_min_sub_61b_goodB2GSource(int64_t data); + +static void goodB2G() +{ + int64_t data; + data = 0LL; + data = CWE191_Integer_Underflow__int64_t_min_sub_61b_goodB2GSource(data); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +void CWE191_Integer_Underflow__int64_t_min_sub_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_sub_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_sub_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fscanf_postdec_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_postdec_54d.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_fscanf_postdec_54e_badSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_postdec_54d_badSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_postdec_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_fscanf_postdec_54e_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_postdec_54d_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_postdec_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_fscanf_postdec_54e_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_fscanf_postdec_54d_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_fscanf_postdec_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_52a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_52a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-52a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_52b_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_52_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE191_Integer_Underflow__unsigned_int_rand_predec_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_52b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__unsigned_int_rand_predec_52b_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_predec_52b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + CWE191_Integer_Underflow__unsigned_int_rand_predec_52b_goodB2GSink(data); +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_52_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_fscanf_multiply_14.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_fscanf_multiply_14.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_fscanf_multiply_14_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_fscanf_multiply_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_fscanf_multiply_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_fscanf_multiply_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_predec_67a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_67a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-67a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE191_Integer_Underflow__char_rand_predec_67_structType +{ + char structFirst; +} CWE191_Integer_Underflow__char_rand_predec_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_rand_predec_67b_badSink(CWE191_Integer_Underflow__char_rand_predec_67_structType myStruct); + +void CWE191_Integer_Underflow__char_rand_predec_67_bad() +{ + char data; + CWE191_Integer_Underflow__char_rand_predec_67_structType myStruct; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_rand_predec_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_rand_predec_67b_goodG2BSink(CWE191_Integer_Underflow__char_rand_predec_67_structType myStruct); + +static void goodG2B() +{ + char data; + CWE191_Integer_Underflow__char_rand_predec_67_structType myStruct; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_rand_predec_67b_goodG2BSink(myStruct); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_rand_predec_67b_goodB2GSink(CWE191_Integer_Underflow__char_rand_predec_67_structType myStruct); + +static void goodB2G() +{ + char data; + CWE191_Integer_Underflow__char_rand_predec_67_structType myStruct; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + myStruct.structFirst = data; + CWE191_Integer_Underflow__char_rand_predec_67b_goodB2GSink(myStruct); +} + +void CWE191_Integer_Underflow__char_rand_predec_67_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_predec_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_predec_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_rand_postdec_18.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_rand_postdec_18.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_rand_postdec_18_bad() +{ + short data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + short data; + data = 0; + goto source; +source: + /* POTENTIAL FLAW: Use a random value */ + data = (short)RAND32(); + goto sink; +sink: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + short data; + data = 0; + goto source; +source: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goto sink; +sink: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +void CWE191_Integer_Underflow__short_rand_postdec_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_rand_postdec_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_rand_postdec_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_rand_predec_01.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_01.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-01.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_predec_01_bad() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char data; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char data; + data = ' '; + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +void CWE191_Integer_Underflow__char_rand_predec_01_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_predec_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_predec_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_45.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_45.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include +#include ""std_testcase.h"" + +static int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_badData; +static int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_goodG2BData; +static int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%"" SCNd64, &data); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_fscanf_postdec_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_min_multiply_31.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_multiply_31.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_multiply_31_bad() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + { + short dataCopy = data; + short data = dataCopy; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + short data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + { + short dataCopy = data; + short data = dataCopy; + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + short data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + { + short dataCopy = data; + short data = dataCopy; + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +void CWE191_Integer_Underflow__short_min_multiply_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_multiply_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_multiply_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_predec_68b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_predec_68b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern short CWE191_Integer_Underflow__short_fscanf_predec_68_badData; +extern short CWE191_Integer_Underflow__short_fscanf_predec_68_goodG2BData; +extern short CWE191_Integer_Underflow__short_fscanf_predec_68_goodB2GData; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_fscanf_predec_68b_badSink() +{ + short data = CWE191_Integer_Underflow__short_fscanf_predec_68_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_fscanf_predec_68b_goodG2BSink() +{ + short data = CWE191_Integer_Underflow__short_fscanf_predec_68_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_fscanf_predec_68b_goodB2GSink() +{ + short data = CWE191_Integer_Underflow__short_fscanf_predec_68_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + --data; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_predec_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_predec_54e.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_predec_54e_badSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_rand_predec_54e_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_rand_predec_54e_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_10.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_10.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_10_bad() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_sub_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_10.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_10.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_10_bad() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + } + if(globalTrue) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_sub_21.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_sub_21.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(int64_t data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_sub_21_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(int64_t data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +static void goodB2G1() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(int64_t data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + int64_t result = data - 1; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +static void goodB2G2() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(int64_t data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + int64_t result = data - 1; + printLongLongLine(result); + } + } +} + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE191_Integer_Underflow__int64_t_min_sub_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_sub_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_sub_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_fscanf_postdec_68b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_fscanf_postdec_68b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_68_badData; +extern int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_68_goodG2BData; +extern int64_t CWE191_Integer_Underflow__int64_t_fscanf_postdec_68_goodB2GData; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_68b_badSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_68_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_68b_goodG2BSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_68_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int64_t_fscanf_postdec_68b_goodB2GSink() +{ + int64_t data = CWE191_Integer_Underflow__int64_t_fscanf_postdec_68_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__int_rand_multiply_02.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_rand_multiply_02.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_rand_multiply_02_bad() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (INT_MIN/2)) + { + int result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = 0; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = 0; + if(1) + { + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + } + if(1) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < INT_MIN, this will underflow */ + int result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__int_rand_multiply_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_rand_multiply_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_rand_multiply_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_postdec_15.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_postdec_15.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_15_bad() +{ + unsigned int data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + unsigned int data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + unsigned int data; + data = 0; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + data--; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + unsigned int data; + data = 0; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + unsigned int data; + data = 0; + switch(6) + { + case 6: + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_postdec_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_postdec_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_rand_postdec_32.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_rand_postdec_32.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_rand_postdec_32_bad() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + int64_t result = data; + printLongLongLine(result); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int64_t data; + int64_t *dataPtr1 = &data; + int64_t *dataPtr2 = &data; + data = 0LL; + { + int64_t data = *dataPtr1; + /* POTENTIAL FLAW: Use a random value */ + data = (int64_t)RAND64(); + *dataPtr1 = data; + } + { + int64_t data = *dataPtr2; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > LLONG_MIN) + { + data--; + int64_t result = data; + printLongLongLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +void CWE191_Integer_Underflow__int64_t_rand_postdec_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_rand_postdec_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_rand_postdec_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__short_fscanf_multiply_61a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_fscanf_multiply_61a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +short CWE191_Integer_Underflow__short_fscanf_multiply_61b_badSource(short data); + +void CWE191_Integer_Underflow__short_fscanf_multiply_61_bad() +{ + short data; + data = 0; + data = CWE191_Integer_Underflow__short_fscanf_multiply_61b_badSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +short CWE191_Integer_Underflow__short_fscanf_multiply_61b_goodG2BSource(short data); + +static void goodG2B() +{ + short data; + data = 0; + data = CWE191_Integer_Underflow__short_fscanf_multiply_61b_goodG2BSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +short CWE191_Integer_Underflow__short_fscanf_multiply_61b_goodB2GSource(short data); + +static void goodB2G() +{ + short data; + data = 0; + data = CWE191_Integer_Underflow__short_fscanf_multiply_61b_goodB2GSource(data); + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } +} + +void CWE191_Integer_Underflow__short_fscanf_multiply_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_fscanf_multiply_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_postdec_22a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_postdec_22a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-22a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the sink function */ +int CWE191_Integer_Underflow__int64_t_min_postdec_22_badGlobal = 0; + +void CWE191_Integer_Underflow__int64_t_min_postdec_22_badSink(int64_t data); + +void CWE191_Integer_Underflow__int64_t_min_postdec_22_bad() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + CWE191_Integer_Underflow__int64_t_min_postdec_22_badGlobal = 1; /* true */ + CWE191_Integer_Underflow__int64_t_min_postdec_22_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the sink functions. */ +int CWE191_Integer_Underflow__int64_t_min_postdec_22_goodB2G1Global = 0; +int CWE191_Integer_Underflow__int64_t_min_postdec_22_goodB2G2Global = 0; +int CWE191_Integer_Underflow__int64_t_min_postdec_22_goodG2BGlobal = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +void CWE191_Integer_Underflow__int64_t_min_postdec_22_goodB2G1Sink(int64_t data); + +static void goodB2G1() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + CWE191_Integer_Underflow__int64_t_min_postdec_22_goodB2G1Global = 0; /* false */ + CWE191_Integer_Underflow__int64_t_min_postdec_22_goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +void CWE191_Integer_Underflow__int64_t_min_postdec_22_goodB2G2Sink(int64_t data); + +static void goodB2G2() +{ + int64_t data; + data = 0LL; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + CWE191_Integer_Underflow__int64_t_min_postdec_22_goodB2G2Global = 1; /* true */ + CWE191_Integer_Underflow__int64_t_min_postdec_22_goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +void CWE191_Integer_Underflow__int64_t_min_postdec_22_goodG2BSink(int64_t data); + +static void goodG2B() +{ + int64_t data; + data = 0LL; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__int64_t_min_postdec_22_goodG2BGlobal = 1; /* true */ + CWE191_Integer_Underflow__int64_t_min_postdec_22_goodG2BSink(data); +} + +void CWE191_Integer_Underflow__int64_t_min_postdec_22_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_postdec_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_postdec_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_min_sub_53d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_sub_53d.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-53d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_sub_53d_badSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_min_sub_53d_goodG2BSink(char data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_min_sub_53d_goodB2GSink(char data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_multiply_04.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_multiply_04.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_multiply_04_bad() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = SHRT_MIN; + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (SHRT_MIN/2)) + { + short result = data * 2; + printIntLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + short data; + data = 0; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + short data; + data = 0; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(STATIC_CONST_TRUE) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < SHRT_MIN, this will underflow */ + short result = data * 2; + printIntLine(result); + } + } +} + +void CWE191_Integer_Underflow__short_min_multiply_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__short_min_multiply_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__short_min_multiply_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_predec_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_66a.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_listen_socket_predec_66b_badSink(int dataArray[]); + +void CWE191_Integer_Underflow__int_listen_socket_predec_66_bad() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__int_listen_socket_predec_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_66b_goodG2BSink(int dataArray[]); + +static void goodG2B() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + /* FIX: Use a small, non-zero value that will not cause an integer underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__int_listen_socket_predec_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_66b_goodB2GSink(int dataArray[]); + +static void goodB2G() +{ + int data; + int dataArray[5]; + /* Initialize data */ + data = 0; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + dataArray[2] = data; + CWE191_Integer_Underflow__int_listen_socket_predec_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__int_listen_socket_predec_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int_listen_socket_predec_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__unsigned_int_rand_postdec_65a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_postdec_65a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_badSink(unsigned int data); + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_65_bad() +{ + unsigned int data; + /* define a function pointer */ + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_badSink; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_goodG2BSink(unsigned int data); + +static void goodG2B() +{ + unsigned int data; + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_goodG2BSink; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_goodB2GSink(unsigned int data); + +static void goodB2G() +{ + unsigned int data; + void (*funcPtr) (unsigned int) = CWE191_Integer_Underflow__unsigned_int_rand_postdec_65b_goodB2GSink; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + funcPtr(data); +} + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_postdec_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_postdec_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_postdec_54d.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_postdec_54d.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_postdec_54e_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_postdec_54d_badSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_postdec_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_postdec_54e_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_postdec_54d_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_postdec_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_postdec_54e_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_postdec_54d_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_postdec_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__short_min_postdec_64b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__short_min_postdec_64b.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for short + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__short_min_postdec_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__short_min_postdec_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + short result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__short_min_postdec_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + short * dataPtr = (short *)dataVoidPtr; + /* dereference dataPtr into data */ + short data = (*dataPtr); + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > SHRT_MIN) + { + data--; + short result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_predec_21.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_predec_21.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(unsigned int data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_21_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(unsigned int data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G1() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(unsigned int data) +{ + if(goodB2G2Static) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +static void goodB2G2() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(unsigned int data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } + } +} + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE191_Integer_Underflow__unsigned_int_rand_predec_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_rand_predec_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_predec_51b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_predec_51b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_connect_socket_predec_51b_badSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_predec_51b_goodG2BSink(int data) +{ + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_predec_51b_goodB2GSink(int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_rand_sub_54e.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_rand_sub_54e.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_54e_badSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_54e_goodG2BSink(unsigned int data) +{ + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__unsigned_int_rand_sub_54e_goodB2GSink(unsigned int data) +{ + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + unsigned int result = data - 1; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_rand_predec_14.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_rand_predec_14.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: rand Set data to result of rand() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_rand_predec_14_bad() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* POTENTIAL FLAW: Use a random value */ + data = (char)RAND32(); + } + if(globalFive==5) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + --data; + char result = data; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char data; + data = ' '; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(globalFive==5) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + char result = data; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_rand_predec_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_rand_predec_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_rand_predec_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_listen_socket_predec_67b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_listen_socket_predec_67b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +typedef struct _CWE191_Integer_Underflow__int_listen_socket_predec_67_structType +{ + int structFirst; +} CWE191_Integer_Underflow__int_listen_socket_predec_67_structType; + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int_listen_socket_predec_67b_badSink(CWE191_Integer_Underflow__int_listen_socket_predec_67_structType myStruct) +{ + int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_67b_goodG2BSink(CWE191_Integer_Underflow__int_listen_socket_predec_67_structType myStruct) +{ + int data = myStruct.structFirst; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + int result = data; + printIntLine(result); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_listen_socket_predec_67b_goodB2GSink(CWE191_Integer_Underflow__int_listen_socket_predec_67_structType myStruct) +{ + int data = myStruct.structFirst; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > INT_MIN) + { + --data; + int result = data; + printIntLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__unsigned_int_min_predec_45.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__unsigned_int_min_predec_45.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for unsigned int + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: decrement + * GoodSink: Ensure there will not be an underflow before decrementing data + * BadSink : Decrement data, which can cause an Underflow + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static unsigned int CWE191_Integer_Underflow__unsigned_int_min_predec_45_badData; +static unsigned int CWE191_Integer_Underflow__unsigned_int_min_predec_45_goodG2BData; +static unsigned int CWE191_Integer_Underflow__unsigned_int_min_predec_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + unsigned int data = CWE191_Integer_Underflow__unsigned_int_min_predec_45_badData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +void CWE191_Integer_Underflow__unsigned_int_min_predec_45_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + CWE191_Integer_Underflow__unsigned_int_min_predec_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + unsigned int data = CWE191_Integer_Underflow__unsigned_int_min_predec_45_goodG2BData; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} + +static void goodG2B() +{ + unsigned int data; + data = 0; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + CWE191_Integer_Underflow__unsigned_int_min_predec_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + unsigned int data = CWE191_Integer_Underflow__unsigned_int_min_predec_45_goodB2GData; + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > 0) + { + --data; + unsigned int result = data; + printUnsignedLine(result); + } + else + { + printLine(""data value is too large to perform arithmetic safely.""); + } +} + +static void goodB2G() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + CWE191_Integer_Underflow__unsigned_int_min_predec_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE191_Integer_Underflow__unsigned_int_min_predec_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__unsigned_int_min_predec_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__unsigned_int_min_predec_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int64_t_min_multiply_10.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int64_t_min_multiply_10.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for int64_t + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: multiply + * GoodSink: Ensure there will not be an underflow before multiplying data by 2 + * BadSink : If data is negative, multiply by 2, which can cause an underflow + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__int64_t_min_multiply_10_bad() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(globalTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = LLONG_MIN; + } + if(globalTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > (LLONG_MIN/2)) + { + int64_t result = data * 2; + printLongLongLine(result); + } + else + { + printLine(""data value is too small to perform multiplication.""); + } + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int64_t data; + data = 0LL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int64_t data; + data = 0LL; + if(globalTrue) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalTrue) + { + if(data < 0) /* ensure we won't have an overflow */ + { + /* POTENTIAL FLAW: if (data * 2) < LLONG_MIN, this will underflow */ + int64_t result = data * 2; + printLongLongLine(result); + } + } +} + +void CWE191_Integer_Underflow__int64_t_min_multiply_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__int64_t_min_multiply_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__char_fscanf_sub_66a.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_fscanf_sub_66a.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-66a.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__char_fscanf_sub_66b_badSink(char dataArray[]); + +void CWE191_Integer_Underflow__char_fscanf_sub_66_bad() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + /* put data in array */ + dataArray[2] = data; + CWE191_Integer_Underflow__char_fscanf_sub_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__char_fscanf_sub_66b_goodG2BSink(char dataArray[]); + +static void goodG2B() +{ + char data; + char dataArray[5]; + data = ' '; + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + dataArray[2] = data; + CWE191_Integer_Underflow__char_fscanf_sub_66b_goodG2BSink(dataArray); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__char_fscanf_sub_66b_goodB2GSink(char dataArray[]); + +static void goodB2G() +{ + char data; + char dataArray[5]; + data = ' '; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, ""%c"", &data); + dataArray[2] = data; + CWE191_Integer_Underflow__char_fscanf_sub_66b_goodB2GSink(dataArray); +} + +void CWE191_Integer_Underflow__char_fscanf_sub_66_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_fscanf_sub_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_fscanf_sub_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE191_Integer_Underflow__int_connect_socket_sub_52b.c,CWE191,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__int_connect_socket_sub_52b.c +Label Definition File: CWE191_Integer_Underflow__int.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE191_Integer_Underflow__int_connect_socket_sub_52c_badSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_sub_52b_badSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_sub_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_52c_goodG2BSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_sub_52b_goodG2BSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_sub_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE191_Integer_Underflow__int_connect_socket_sub_52c_goodB2GSink(int data); + +void CWE191_Integer_Underflow__int_connect_socket_sub_52b_goodB2GSink(int data) +{ + CWE191_Integer_Underflow__int_connect_socket_sub_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE191_Integer_Underflow__char_min_sub_11.c,CWE191,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE191_Integer_Underflow__char_min_sub_11.c +Label Definition File: CWE191_Integer_Underflow.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 191 Integer Underflow + * BadSource: min Set data to the min value for char + * GoodSource: Set data to a small, non-zero number (negative two) + * Sinks: sub + * GoodSink: Ensure there will not be an underflow before subtracting 1 from data + * BadSink : Subtract 1 from data, which can cause an Underflow + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE191_Integer_Underflow__char_min_sub_11_bad() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = CHAR_MIN; + } + if(globalReturnsTrue()) + { + /* FIX: Add a check to prevent an underflow from occurring */ + if (data > CHAR_MIN) + { + char result = data - 1; + printHexCharLine(result); + } + else + { + printLine(""data value is too large to perform subtraction.""); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char data; + data = ' '; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + char data; + data = ' '; + if(globalReturnsTrue()) + { + /* FIX: Use a small, non-zero value that will not cause an underflow in the sinks */ + data = -2; + } + if(globalReturnsTrue()) + { + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + char result = data - 1; + printHexCharLine(result); + } + } +} + +void CWE191_Integer_Underflow__char_min_sub_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE191_Integer_Underflow__char_min_sub_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE191_Integer_Underflow__char_min_sub_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_41.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_41.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-41.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_41_bad() +{ + int data; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + goodB2GSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_41_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_06_bad() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_16_bad() +{ + int data; + /* Initialize data */ + data = -1; + while(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + break; + } + while(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the sinks in the second while statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + while(1) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + break; + } + while(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + break; + } +} + +/* goodG2B() - use goodsource and badsink by changing the sources in the first while statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + while(1) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + break; + } + while(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + break; + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_16_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_11.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_11.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_11_bad() +{ + int * data; + data = NULL; + if(globalReturnsTrue()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(globalReturnsTrue()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_12_bad() +{ + char * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sinks: + * BadSink : Print then free data + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int64_t * CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61b_badSource(int64_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61_bad() +{ + int64_t * data; + /* Initialize data */ + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61b_badSource(data); + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printLongLongLine(*data); + free(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int64_t * CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61b_goodG2BSource(int64_t * data); + +static void goodG2B() +{ + int64_t * data; + /* Initialize data */ + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61b_goodG2BSource(data); + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printLongLongLine(*data); + free(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +static char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_badData; +static char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_badData; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_goodG2BData; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_53d_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_53d_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_05_bad() +{ + int64_t * data; + data = NULL; + if(staticTrue) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + int64_t * data; + data = NULL; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + free(data); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int64_t * data; + data = NULL; + if(staticTrue) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_67b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_67b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-67b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__CWE135_67_structType +{ + void * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__CWE135_67_structType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__CWE135_67_structType myStruct) +{ + void * data = myStruct.structFirst; + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printLine((char *)dest); + free(dest); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__CWE135_67_structType myStruct) +{ + void * data = myStruct.structFirst; + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, 1); + if (dest == NULL) {exit(-1);} + (void)strcpy(dest, data); + printLine((char *)dest); + free(dest); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_67b_goodB2GSink(CWE122_Heap_Based_Buffer_Overflow__CWE135_67_structType myStruct) +{ + void * data = myStruct.structFirst; + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + free(dest); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_42.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_42.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-42.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static int badSource(int data) +{ + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_42_bad() +{ + int data; + /* Initialize data */ + data = -1; + data = badSource(data); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static int goodG2BSource(int data) +{ + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + return data; +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + data = goodG2BSource(data); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +static int goodB2GSource(int data) +{ + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + return data; +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + data = goodB2GSource(data); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_42_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_15.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_15.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-15.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_15_bad() +{ + switch(6) + { + case 6: + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() changes the switch to switch(5) */ +static void good1() +{ + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + break; + } +} + +/* good2() reverses the blocks in the switch */ +static void good2() +{ + switch(6) + { + case 6: + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_15_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_15.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_15.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: large Large index value that is greater than 10-1 + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_15_bad() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + break; + } + switch(7) + { + case 7: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_44.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34_unionType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34_bad() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34_unionType myUnion; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34_unionType myUnion; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_52c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_52c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_52c_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_52c_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66b_badSink(wchar_t * dataArray[]); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66_bad() +{ + wchar_t * data; + wchar_t * dataArray[5]; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66b_goodG2BSink(wchar_t * dataArray[]); + +static void goodG2B() +{ + wchar_t * data; + wchar_t * dataArray[5]; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + dataArray[2] = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66b_goodG2BSink(dataArray); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54_bad() +{ + char * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_52c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_52c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_52c_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_52c_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_53c_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_53b_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_53c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_53b_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_06_bad() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-45.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +static int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_badData; +static int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_goodG2BData; +static int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_goodB2GData; + +#ifndef OMITBAD + +static void badSink() +{ + int data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_badData; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_bad() +{ + int data; + /* Initialize data */ + data = -1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_goodG2BData; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_goodG2BData = data; + goodG2BSink(); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink() +{ + int data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_goodB2GData; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_goodB2GData = data; + goodB2GSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_09.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_09.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_09_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(GLOBAL_CONST_TRUE) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using wcscpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_52c_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_52b_badSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_52c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_52b_goodG2BSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_14_bad() +{ + char * data; + data = NULL; + if(globalFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(globalFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_11.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_11.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_11_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_badData; +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68b_badSink(); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_badData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_goodG2BData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68b_goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sink: + * BadSink : Print then free data + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_53c_badSink(twoIntsStruct * data); + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_53b_badSink(twoIntsStruct * data) +{ + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_53c_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_53b_goodG2BSink(twoIntsStruct * data) +{ + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_67b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_67b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sinks: + * BadSink : Print then free data + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_67_structType +{ + twoIntsStruct * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_67_structType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_67_structType myStruct) +{ + twoIntsStruct * data = myStruct.structFirst; + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printStructLine(data); + free(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_67_structType myStruct) +{ + twoIntsStruct * data = myStruct.structFirst; + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printStructLine(data); + free(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_14.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_14_bad() +{ + char * data; + data = NULL; + if(globalFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(globalFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_63b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_63b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-53c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53d_badSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53c_badSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53d_goodG2BSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53c_goodG2BSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53d_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53d_goodB2GSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53c_goodB2GSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_53d_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-61a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61b_badSource(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61_bad() +{ + int data; + /* Initialize data */ + data = -1; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61b_badSource(data); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61b_goodG2BSource(int data); + +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61b_goodG2BSource(data); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61b_goodB2GSource(int data); + +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61b_goodB2GSource(data); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_54e_badSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_54e_goodG2BSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_54e_goodB2GSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_18.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_18.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-18.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memcpy + * GoodSink: Perform the memcpy() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memcpy() + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_18_bad() +{ + goto sink; +sink: + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + free(structCharVoid); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() reverses the blocks on the goto statement */ +static void good1() +{ + goto sink; +sink: + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + free(structCharVoid); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_18_good() +{ + good1(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_18.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_18.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_18_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + goto source; +source: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + goto source; +source: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_15.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_15.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_15_bad() +{ + wchar_t * data; + data = NULL; + switch(6) + { + case 6: + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + switch(6) + { + case 6: + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_03.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_03.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_03_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(5==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(5==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(5==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_68b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_68b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_68_badData; +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_68b_badSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_68_badData; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, ""%s"", source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_68b_goodG2BSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_68_goodG2BData; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, ""%s"", source); + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR L""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + wchar_t charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_08_bad() +{ + if(staticReturnsTrue()) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(staticReturnsFalse()) instead of if(staticReturnsTrue()) */ +static void good1() +{ + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(staticReturnsTrue()) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_08_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66b_badSink(char * dataArray[]); + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66_bad() +{ + char * data; + char * dataArray[5]; + data = (char *)malloc(100*sizeof(char)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + data = (char *)malloc(100*sizeof(char)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + dataArray[2] = data; + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66b_goodG2BSink(dataArray); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53c_badSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53b_badSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53c_goodG2BSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53b_goodG2BSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53c_goodB2GSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53b_goodB2GSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_53c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_badGlobal; + +int64_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_badSource(int64_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_badGlobal) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_goodG2B1Global; +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +int64_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_goodG2B1Source(int64_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +int64_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_goodG2B2Source(int64_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_22_goodG2B2Global) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34_unionType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34_bad() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34_unionType myUnion; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34_unionType myUnion; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_02.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_02.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_02_bad() +{ + char * data; + data = NULL; + if(1) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(1) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_12_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(globalReturnsTrueOrFalse()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53b_badSink(twoIntsStruct * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53_bad() +{ + twoIntsStruct * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53b_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + twoIntsStruct * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_68b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_68b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_68_badData; +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_68b_badSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_68_badData; + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_68b_goodG2BSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_68_goodG2BData; + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53d_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53c_badSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53c_goodG2BSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_61b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_61b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +twoIntsStruct * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_61b_badSource(twoIntsStruct * data) +{ + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +twoIntsStruct * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_61b_goodG2BSource(twoIntsStruct * data) +{ + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_52c_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_52b_badSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_52c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_52b_goodG2BSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_14_bad() +{ + int * data; + data = NULL; + if(globalFive==5) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(globalFive==5) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_68b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_68b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_68_badData; +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_68b_badSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_68_badData; + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_68b_goodG2BSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_68_goodG2BData; + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_54c_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_54b_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_54b_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_17.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_17.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_17_bad() +{ + int i; + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + for(i = 0; i < 1; i++) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + for(h = 0; h < 1; h++) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_34.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_34.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-34.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + void * unionFirst; + void * unionSecond; +} CWE122_Heap_Based_Buffer_Overflow__CWE135_34_unionType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_34_bad() +{ + void * data; + CWE122_Heap_Based_Buffer_Overflow__CWE135_34_unionType myUnion; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + myUnion.unionFirst = data; + { + void * data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + void * data; + CWE122_Heap_Based_Buffer_Overflow__CWE135_34_unionType myUnion; + data = NULL; + { + char * dataGoodBuffer = (char *)malloc(50*sizeof(char)); + if (dataGoodBuffer == NULL) {exit(-1);} + memset(dataGoodBuffer, 'A', 50-1); + dataGoodBuffer[50-1] = '\0'; + /* FIX: Set data to point to a char string */ + data = (void *)dataGoodBuffer; + } + myUnion.unionFirst = data; + { + void * data = myUnion.unionSecond; + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, 1); + if (dest == NULL) {exit(-1);} + (void)strcpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + void * data; + CWE122_Heap_Based_Buffer_Overflow__CWE135_34_unionType myUnion; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + myUnion.unionFirst = data; + { + void * data = myUnion.unionSecond; + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + free(dest); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_34_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61b_badSource(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61_bad() +{ + wchar_t * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61b_badSource(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61b_goodG2BSource(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_badGlobal; + +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_badSource(char * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_badGlobal) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_goodG2B1Global; +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_goodG2B1Source(char * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_goodG2B2Source(char * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_22_goodG2B2Global) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65b_badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65b_goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52b_badSink(int64_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52_bad() +{ + int64_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52b_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_31.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_31.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using wcscpy + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_31_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_52c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_52c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_52c_badSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_52c_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64b_badSink(void * dataVoidPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_12_bad() +{ + twoIntsStruct * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + twoIntsStruct * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_54c_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_54b_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_54b_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sinks: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_structType +{ + int * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_structType myStruct); + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_bad() +{ + int * data; + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_structType myStruct; + data = NULL; + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_structType myStruct); + +static void goodG2B() +{ + int * data; + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_structType myStruct; + data = NULL; + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67b_goodG2BSink(myStruct); +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_11.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_11.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_11_bad() +{ + wchar_t * data; + data = NULL; + if(globalReturnsTrue()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(globalReturnsTrue()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_08_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticReturnsTrue()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticReturnsTrue()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-22a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +int CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_badGlobal = 0; + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_badSource(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_bad() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_badGlobal = 1; /* true */ + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_badSource(data); + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +int CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_goodG2B1Global = 0; +int CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_goodG2B2Global = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_goodG2B1Source(wchar_t * data); + +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_goodG2B1Global = 0; /* false */ + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_goodG2B1Source(data); + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_goodG2B2Source(wchar_t * data); + +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_goodG2B2Global = 1; /* true */ + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_goodG2B2Source(data); + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_09.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_09.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-09.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_09_bad() +{ + if(GLOBAL_CONST_TRUE) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(GLOBAL_CONST_FALSE) instead of if(GLOBAL_CONST_TRUE) */ +static void good1() +{ + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(GLOBAL_CONST_TRUE) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_09_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_32.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_32.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_32_bad() +{ + int * data; + int * *dataPtr1 = &data; + int * *dataPtr2 = &data; + data = NULL; + { + int * data = *dataPtr1; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + *dataPtr1 = data; + } + { + int * data = *dataPtr2; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + int * *dataPtr1 = &data; + int * *dataPtr2 = &data; + data = NULL; + { + int * data = *dataPtr1; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + *dataPtr1 = data; + } + { + int * data = *dataPtr2; + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_32.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_32.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_32_bad() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + data = NULL; + { + char * data = *dataPtr1; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + data = NULL; + { + char * data = *dataPtr1; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_52c_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_52b_badSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_52c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_52b_goodG2BSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: large Large index value that is greater than 10-1 + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + should be able to identify that calls to the functions will always + return a fixed value. */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_08_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(staticReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticReturnsTrue() to staticReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(staticReturnsTrue()) + { + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + } + if(staticReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(staticReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(staticReturnsTrue()) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(staticReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_08_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_badGlobal; + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_badSource(wchar_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_badGlobal) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_goodG2B1Global; +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_goodG2B1Source(wchar_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_goodG2B2Source(wchar_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_22_goodG2B2Global) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_12_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrueOrFalse()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by changing the first ""if"" so that + both branches use the BadSource and the second ""if"" so that both branches + use the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrueOrFalse()) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + else + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalReturnsTrueOrFalse()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B() - use goodsource and badsink by changing the first ""if"" so that + both branches use the GoodSource and the second ""if"" so that both branches + use the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrueOrFalse()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_12_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_12_bad() +{ + wchar_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcscat(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcscat(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65b_badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65b_goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +int * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61b_badSource(int * data) +{ + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +int * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61b_goodG2BSource(int * data) +{ + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_31.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_31.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_31_bad() +{ + int64_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + { + int64_t * dataCopy = data; + int64_t * data = dataCopy; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + { + int64_t * dataCopy = data; + int64_t * data = dataCopy; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_21.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_21.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static char * badSource(char * data) +{ + if(badStatic) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_21_bad() +{ + char * data; + data = NULL; + badStatic = 1; /* true */ + data = badSource(data); + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static char * goodG2B1Source(char * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + return data; +} + +static void goodG2B1() +{ + char * data; + data = NULL; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static char * goodG2B2Source(char * data) +{ + if(goodG2B2Static) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + return data; +} + +static void goodG2B2() +{ + char * data; + data = NULL; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68_badData; +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68b_badSink(); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68_badData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68_goodG2BData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68b_goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_15.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_15.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-15.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 15 Control flow: switch(6) and switch(7) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_15_bad() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second switch to switch(8) */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(8) + { + case 7: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + break; + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second switch */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first switch to switch(5) */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + break; + } + switch(7) + { + case 7: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first switch */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + switch(6) + { + case 6: + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + switch(7) + { + case 7: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_15_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_65b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_65b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sinks: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_65b_badSink(int * data) +{ + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_65b_goodG2BSink(int * data) +{ + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_14_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(globalFive==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(globalFive==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_07.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_07_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61b_badSource(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61_bad() +{ + char * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61b_badSource(data); + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61b_goodG2BSource(char * data); + +static void goodG2B() +{ + char * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61b_goodG2BSource(data); + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_42.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_42.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +static char * badSource(char * data) +{ + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_42_bad() +{ + char * data; + data = NULL; + data = badSource(data); + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static char * goodG2BSource(char * data) +{ + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + data = goodG2BSource(data); + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_54e_badSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_54e_goodG2BSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sinks: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static int * CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_badData; +static int * CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + int * data = CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_badData; + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_bad() +{ + int * data; + data = NULL; + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int * data = CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_goodG2BData; + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +static void goodG2B() +{ + int * data; + data = NULL; + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53d_badSink(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53c_badSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53d_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53c_goodG2BSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_54e_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_54e_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_10.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_10.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_10_bad() +{ + wchar_t * data; + data = NULL; + if(globalTrue) + { + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(globalTrue) + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_31.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_31.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_31_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_11.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_11.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_11_bad() +{ + twoIntsStruct * data; + data = NULL; + if(globalReturnsTrue()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + twoIntsStruct * data; + data = NULL; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + data = NULL; + if(globalReturnsTrue()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR L""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + wchar_t charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_06_bad() +{ + if(STATIC_CONST_FIVE==5) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(STATIC_CONST_FIVE!=5) instead of if(STATIC_CONST_FIVE==5) */ +static void good1() +{ + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(STATIC_CONST_FIVE==5) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_06_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_04.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_04.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_04_bad() +{ + char * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_44_bad() +{ + int64_t * data; + /* define a function pointer */ + void (*funcPtr) (int64_t *) = badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +static void goodG2B() +{ + int64_t * data; + void (*funcPtr) (int64_t *) = goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64b_badSink(void * dataVoidPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_13.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_13.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-13.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_13_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(GLOBAL_CONST_FIVE==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_13_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_05_bad() +{ + wchar_t * data; + data = NULL; + if(staticTrue) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(staticTrue) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_53c_badSink(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_53b_badSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_53c_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_53b_goodG2BSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_63a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_63a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-63a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_63b_badSink(void * * dataPtr); + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_63_bad() +{ + void * data; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + CWE122_Heap_Based_Buffer_Overflow__CWE135_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_63b_goodG2BSink(void * * data); + +static void goodG2B() +{ + void * data; + data = NULL; + { + char * dataGoodBuffer = (char *)malloc(50*sizeof(char)); + if (dataGoodBuffer == NULL) {exit(-1);} + memset(dataGoodBuffer, 'A', 50-1); + dataGoodBuffer[50-1] = '\0'; + /* FIX: Set data to point to a char string */ + data = (void *)dataGoodBuffer; + } + CWE122_Heap_Based_Buffer_Overflow__CWE135_63b_goodG2BSink(&data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_63b_goodB2GSink(void * * data); + +static void goodB2G() +{ + void * data; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + CWE122_Heap_Based_Buffer_Overflow__CWE135_63b_goodB2GSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_63_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_16.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_16_bad() +{ + while(1) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses the GoodSinkBody in the while loop */ +static void good1() +{ + while(1) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + break; + } +} + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_16_good() +{ + good1(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_14_bad() +{ + char * data; + data = NULL; + if(globalFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(globalFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memcpy + * GoodSink: Perform the memcpy() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memcpy() + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR L""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + wchar_t charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_12_bad() +{ + if(globalReturnsTrueOrFalse()) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + free(structCharVoid); + } + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + free(structCharVoid); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses the GoodSink on both sides of the ""if"" statement */ +static void good1() +{ + if(globalReturnsTrueOrFalse()) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + free(structCharVoid); + } + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + free(structCharVoid); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_12_good() +{ + good1(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41_badSink(int * data) +{ + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41_bad() +{ + int * data; + data = NULL; + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41_goodG2BSink(int * data) +{ + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + data = NULL; + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_64b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_64b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_44.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + free(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_04.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_04.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_04_bad() +{ + char * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_64b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_64b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_65b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_65b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-65b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_65b_badSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_65b_goodG2BSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_65b_goodB2GSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_02.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_02.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_02_bad() +{ + char * data; + data = NULL; + if(1) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(1) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_21.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_21.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static int * badSource(int * data) +{ + if(badStatic) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + } + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_21_bad() +{ + int * data; + data = NULL; + badStatic = 1; /* true */ + data = badSource(data); + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static int * goodG2B1Source(int * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + } + return data; +} + +static void goodG2B1() +{ + int * data; + data = NULL; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static int * goodG2B2Source(int * data) +{ + if(goodG2B2Static) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + } + return data; +} + +static void goodG2B2() +{ + int * data; + data = NULL; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_65b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_65b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_65b_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_65b_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_54e_badSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_54e_goodG2BSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +static char * CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_badData; +static char * CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_badData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_goodG2BData; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + free(data); + } +} + +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_16_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + while(1) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + while(1) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + break; + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_44.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: cpy + * BadSink : Copy string to data using wcscpy() + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_badGlobal; + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_badSource(wchar_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_badGlobal) + { + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_goodG2B1Global; +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_goodG2B1Source(wchar_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_goodG2B2Source(wchar_t * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_cpy_22_goodG2B2Global) + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_07.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_07_bad() +{ + wchar_t * data; + data = NULL; + if(staticFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(staticFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_68b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_68b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_68_badData; +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_68b_badSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_68_badData; + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_68b_goodG2BSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_68_goodG2BData; + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_01.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_01.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_01_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_66b_badSink(twoIntsStruct * dataArray[]) +{ + /* copy data out of dataArray */ + twoIntsStruct * data = dataArray[2]; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_66b_goodG2BSink(twoIntsStruct * dataArray[]) +{ + twoIntsStruct * data = dataArray[2]; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + free(data); + } + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_09.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_09.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_09_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(GLOBAL_CONST_TRUE) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_TRUE) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(GLOBAL_CONST_TRUE) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(GLOBAL_CONST_TRUE) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(GLOBAL_CONST_TRUE) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_67b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_67b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_67_structType +{ + wchar_t * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_67_structType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_05.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_05_bad() +{ + int * data; + data = NULL; + if(staticTrue) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(staticTrue) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65b_badSink; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65b_goodG2BSink; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_08_bad() +{ + wchar_t * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = wcslen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_11.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_11.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_11_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(globalReturnsTrue()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(globalReturnsTrue()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_02.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_02.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_02_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(1) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(1) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(1) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(1) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_12_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(globalReturnsTrueOrFalse()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_15.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_15.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_15_bad() +{ + wchar_t * data; + data = NULL; + switch(6) + { + case 6: + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + break; + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + switch(6) + { + case 6: + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_18.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_18.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_18_bad() +{ + int * data; + data = NULL; + goto source; +source: + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + int * data; + data = NULL; + goto source; +source: + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_63b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_63b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_21.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_21.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sink: + * BadSink : Print then free data + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static twoIntsStruct * badSource(twoIntsStruct * data) +{ + if(badStatic) + { + /* INCIDENTAL: CWE-467 (Use of sizeof() on a pointer type) */ + /* FLAW: Using sizeof the pointer and not the data type in malloc() */ + data = (twoIntsStruct *)malloc(sizeof(data)); + if (data == NULL) {exit(-1);} + data->intOne = 1; + data->intTwo = 2; + } + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_21_bad() +{ + twoIntsStruct * data; + /* Initialize data */ + data = NULL; + badStatic = 1; /* true */ + data = badSource(data); + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printStructLine(data); + free(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static twoIntsStruct * goodG2B1Source(twoIntsStruct * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Using sizeof the data type in malloc() */ + data = (twoIntsStruct *)malloc(sizeof(*data)); + if (data == NULL) {exit(-1);} + data->intOne = 1; + data->intTwo = 2; + } + return data; +} + +static void goodG2B1() +{ + twoIntsStruct * data; + /* Initialize data */ + data = NULL; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printStructLine(data); + free(data); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static twoIntsStruct * goodG2B2Source(twoIntsStruct * data) +{ + if(goodG2B2Static) + { + /* FIX: Using sizeof the data type in malloc() */ + data = (twoIntsStruct *)malloc(sizeof(*data)); + if (data == NULL) {exit(-1);} + data->intOne = 1; + data->intTwo = 2; + } + return data; +} + +static void goodG2B2() +{ + twoIntsStruct * data; + /* Initialize data */ + data = NULL; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printStructLine(data); + free(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_15.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_15.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_15_bad() +{ + twoIntsStruct * data; + data = NULL; + switch(6) + { + case 6: + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + twoIntsStruct * data; + data = NULL; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + break; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + twoIntsStruct * data; + data = NULL; + switch(6) + { + case 6: + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_07.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_07_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticFive==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticFive==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52b_badSink(twoIntsStruct * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52_bad() +{ + twoIntsStruct * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52b_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + twoIntsStruct * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_06_bad() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_53d_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_53d_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_16_bad() +{ + int * data; + data = NULL; + while(1) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + break; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + int * data; + data = NULL; + while(1) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + break; + } + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_53c_badSink(twoIntsStruct * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_53b_badSink(twoIntsStruct * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_53c_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_53b_goodG2BSink(twoIntsStruct * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61b_badSource(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61_bad() +{ + wchar_t * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61b_badSource(data); + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61b_goodG2BSource(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61b_goodG2BSource(data); + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memcpy_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63b_badSink(wchar_t * * dataPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63b_goodG2BSink(wchar_t * * data); + +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_10.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_10.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_10_bad() +{ + char * data; + data = NULL; + if(globalTrue) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(globalTrue) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53_bad() +{ + char * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68_badData; +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68b_badSink(); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68_badData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68_goodG2BData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68b_goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_16_bad() +{ + int64_t * data; + data = NULL; + while(1) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + break; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + int64_t * data; + data = NULL; + while(1) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + break; + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_15.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_15.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_15_bad() +{ + wchar_t * data; + data = NULL; + switch(6) + { + case 6: + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + switch(6) + { + case 6: + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_16_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + while(1) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + break; + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + while(1) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + break; + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sink: + * BadSink : Print then free data + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_08_bad() +{ + twoIntsStruct * data; + /* Initialize data */ + data = NULL; + if(staticReturnsTrue()) + { + /* INCIDENTAL: CWE-467 (Use of sizeof() on a pointer type) */ + /* FLAW: Using sizeof the pointer and not the data type in malloc() */ + data = (twoIntsStruct *)malloc(sizeof(data)); + if (data == NULL) {exit(-1);} + data->intOne = 1; + data->intTwo = 2; + } + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printStructLine(data); + free(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + twoIntsStruct * data; + /* Initialize data */ + data = NULL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Using sizeof the data type in malloc() */ + data = (twoIntsStruct *)malloc(sizeof(*data)); + if (data == NULL) {exit(-1);} + data->intOne = 1; + data->intTwo = 2; + } + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printStructLine(data); + free(data); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + /* Initialize data */ + data = NULL; + if(staticReturnsTrue()) + { + /* FIX: Using sizeof the data type in malloc() */ + data = (twoIntsStruct *)malloc(sizeof(*data)); + if (data == NULL) {exit(-1);} + data->intOne = 1; + data->intTwo = 2; + } + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printStructLine(data); + free(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_54c_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_54b_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_54b_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51b_badSink(twoIntsStruct * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51_bad() +{ + twoIntsStruct * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51b_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + twoIntsStruct * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_61b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_61b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_61b_badSource(char * data) +{ + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_61b_goodG2BSource(char * data) +{ + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_03.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_03.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_03_bad() +{ + char * data; + data = NULL; + if(5==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(5==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-68a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_badData; +int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_goodG2BData; +int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_goodB2GData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68b_badSink(); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_bad() +{ + int data; + /* Initialize data */ + data = -1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_badData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68b_goodG2BSink(); +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68b_goodB2GSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_goodG2BData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68b_goodG2BSink(); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_goodB2GData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68b_goodB2GSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53c_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53b_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53b_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_badSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_goodG2BSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_goodB2GSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63b_badSink(char * * dataPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54e_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54e_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_badGlobal; + +twoIntsStruct * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_badSource(twoIntsStruct * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_badGlobal) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_goodG2B1Global; +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +twoIntsStruct * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_goodG2B1Source(twoIntsStruct * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +twoIntsStruct * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_goodG2B2Source(twoIntsStruct * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_22_goodG2B2Global) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_09.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_09.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-09.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_09_bad() +{ + void * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodB2G1() +{ + void * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + } + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + free(dest); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + void * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + } + if(GLOBAL_CONST_TRUE) + { + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + free(dest); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + void * data; + data = NULL; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + char * dataGoodBuffer = (char *)malloc(50*sizeof(char)); + if (dataGoodBuffer == NULL) {exit(-1);} + memset(dataGoodBuffer, 'A', 50-1); + dataGoodBuffer[50-1] = '\0'; + /* FIX: Set data to point to a char string */ + data = (void *)dataGoodBuffer; + } + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, 1); + if (dest == NULL) {exit(-1);} + (void)strcpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + void * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + { + char * dataGoodBuffer = (char *)malloc(50*sizeof(char)); + if (dataGoodBuffer == NULL) {exit(-1);} + memset(dataGoodBuffer, 'A', 50-1); + dataGoodBuffer[50-1] = '\0'; + /* FIX: Set data to point to a char string */ + data = (void *)dataGoodBuffer; + } + } + if(GLOBAL_CONST_TRUE) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, 1); + if (dest == NULL) {exit(-1);} + (void)strcpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_09_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_07.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_07_bad() +{ + char * data; + data = NULL; + if(staticFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(staticFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_64b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_64b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using wcscpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_06_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64b_badSink(void * dataVoidPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63b_badSink(wchar_t * * dataPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63b_goodG2BSink(wchar_t * * data); + +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41_badSink(wchar_t * data) +{ + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41_goodG2BSink(wchar_t * data) +{ + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_05_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_64b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_64b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-64b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_64b_goodB2GSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + int * dataPtr = (int *)dataVoidPtr; + /* dereference dataPtr into data */ + int data = (*dataPtr); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_63b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_63b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_16.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_16_bad() +{ + int * data; + data = NULL; + while(1) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + break; + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + int * data; + data = NULL; + while(1) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + break; + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64b_badSink(void * dataVoidPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64_bad() +{ + twoIntsStruct * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + twoIntsStruct * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54b_badSink(int64_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54_bad() +{ + int64_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54b_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_12_bad() +{ + int64_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + int64_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_structType +{ + twoIntsStruct * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_structType myStruct); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_bad() +{ + twoIntsStruct * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_structType myStruct; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_structType myStruct); + +static void goodG2B() +{ + twoIntsStruct * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_structType myStruct; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67b_goodG2BSink(myStruct); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54b_badSink(twoIntsStruct * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54_bad() +{ + twoIntsStruct * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54b_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + twoIntsStruct * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_14_bad() +{ + twoIntsStruct * data; + data = NULL; + if(globalFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + twoIntsStruct * data; + data = NULL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + data = NULL; + if(globalFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two variables below are not defined as ""const"", but are never + assigned any other value, so a tool should be able to identify that + reads of these will always return their initialized values. */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_05_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticTrue) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second staticTrue to staticFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(staticTrue) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(staticTrue) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first staticTrue to staticFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(staticTrue) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(staticTrue) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(staticTrue) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_05_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_54c_badSink(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_54b_badSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_54c_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_54b_goodG2BSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_64b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_64b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_02.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_02.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-02.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_02_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 1 to 0 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(1) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 1 to 0 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(1) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(1) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_02_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_51b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_51b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-51b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_51b_badSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_51b_goodG2BSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_51b_goodB2GSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_10.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_10.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_10_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(globalTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(globalTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_61b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_61b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_61b_badSource(wchar_t * data) +{ + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_61b_goodG2BSource(wchar_t * data) +{ + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_14_bad() +{ + void * data; + data = NULL; + if(globalFive==5) + { + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + void * data; + data = NULL; + if(globalFive==5) + { + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + free(dest); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + void * data; + data = NULL; + if(globalFive==5) + { + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + } + if(globalFive==5) + { + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + free(dest); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + void * data; + data = NULL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + char * dataGoodBuffer = (char *)malloc(50*sizeof(char)); + if (dataGoodBuffer == NULL) {exit(-1);} + memset(dataGoodBuffer, 'A', 50-1); + dataGoodBuffer[50-1] = '\0'; + /* FIX: Set data to point to a char string */ + data = (void *)dataGoodBuffer; + } + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, 1); + if (dest == NULL) {exit(-1);} + (void)strcpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + void * data; + data = NULL; + if(globalFive==5) + { + { + char * dataGoodBuffer = (char *)malloc(50*sizeof(char)); + if (dataGoodBuffer == NULL) {exit(-1);} + memset(dataGoodBuffer, 'A', 50-1); + dataGoodBuffer[50-1] = '\0'; + /* FIX: Set data to point to a char string */ + data = (void *)dataGoodBuffer; + } + } + if(globalFive==5) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, 1); + if (dest == NULL) {exit(-1);} + (void)strcpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_10.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_10.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-10.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_10_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalTrue) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalTrue) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalTrue to globalFalse */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalTrue) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalTrue) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(globalTrue) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalTrue to globalFalse */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalTrue) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalTrue) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalTrue) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_10_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR L""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + wchar_t charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_16_bad() +{ + while(1) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + } + break; + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses the GoodSinkBody in the while loop */ +static void good1() +{ + while(1) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + } + break; + } +} + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_16_good() +{ + good1(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memmove_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_04.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_04.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_04_bad() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53d_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53d_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcscat(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_68b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_68b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +extern wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_68_badData; +extern wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_68b_badSink() +{ + wchar_t * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_68_badData; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_68b_goodG2BSink() +{ + wchar_t * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_68_goodG2BData; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52b_badSink(int64_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52_bad() +{ + int64_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52b_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_63b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_63b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_63b_badSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_63b_goodG2BSink(wchar_t * * dataPtr) +{ + wchar_t * data = *dataPtr; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65b_badSink; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65b_goodG2BSink(wchar_t * data); + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65b_goodG2BSink; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_08_bad() +{ + wchar_t * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sink: + * BadSink : Print then free data + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54b_badSink(int64_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54_bad() +{ + int64_t * data; + /* Initialize data */ + data = NULL; + /* INCIDENTAL: CWE-467 (Use of sizeof() on a pointer type) */ + /* FLAW: Using sizeof the pointer and not the data type in malloc() */ + data = (int64_t *)malloc(sizeof(data)); + *data = 2147483643LL; + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54b_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + /* Initialize data */ + data = NULL; + /* FIX: Using sizeof the data type in malloc() */ + data = (int64_t *)malloc(sizeof(*data)); + *data = 2147483643LL; + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_21.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_21.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-21.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the sink function */ +static int badStatic = 0; + +static void badSink(void * data) +{ + if(badStatic) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_21_bad() +{ + void * data; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + badStatic = 1; /* true */ + badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the sink functions. */ +static int goodB2G1Static = 0; +static int goodB2G2Static = 0; +static int goodG2BStatic = 0; + +/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */ +static void goodB2G1Sink(void * data) +{ + if(goodB2G1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + free(dest); + } + } +} + +static void goodB2G1() +{ + void * data; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + goodB2G1Static = 0; /* false */ + goodB2G1Sink(data); +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ +static void goodB2G2Sink(void * data) +{ + if(goodB2G2Static) + { + { + /* FIX: treating pointer like a wchar_t* */ + size_t dataLen = wcslen((wchar_t *)data); + void * dest = (void *)calloc(dataLen+1, sizeof(wchar_t)); + if (dest == NULL) {exit(-1);} + (void)wcscpy(dest, data); + printWLine((wchar_t *)dest); + free(dest); + } + } +} + +static void goodB2G2() +{ + void * data; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + goodB2G2Static = 1; /* true */ + goodB2G2Sink(data); +} + +/* goodG2B() - use goodsource and badsink */ +static void goodG2BSink(void * data) +{ + if(goodG2BStatic) + { + { + /* POTENTIAL FLAW: treating pointer as a char* when it may point to a wide string */ + size_t dataLen = strlen((char *)data); + void * dest = (void *)calloc(dataLen+1, 1); + if (dest == NULL) {exit(-1);} + (void)strcpy(dest, data); + printLine((char *)dest); + free(dest); + } + } +} + +static void goodG2B() +{ + void * data; + data = NULL; + { + char * dataGoodBuffer = (char *)malloc(50*sizeof(char)); + if (dataGoodBuffer == NULL) {exit(-1);} + memset(dataGoodBuffer, 'A', 50-1); + dataGoodBuffer[50-1] = '\0'; + /* FIX: Set data to point to a char string */ + data = (void *)dataGoodBuffer; + } + goodG2BStatic = 1; /* true */ + goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_21_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_64b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_64b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + char * * dataPtr = (char * *)dataVoidPtr; + /* dereference dataPtr into data */ + char * data = (*dataPtr); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_05_bad() +{ + int * data; + data = NULL; + if(staticTrue) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(staticTrue) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_63b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_63b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: large Large index value that is greater than 10-1 + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-22a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +int CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_badGlobal = 0; + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_badSource(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_bad() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_badGlobal = 1; /* true */ + data = CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_badSource(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcscat(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +int CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_goodG2B1Global = 0; +int CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_goodG2B2Global = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_goodG2B1Source(wchar_t * data); + +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_goodG2B1Global = 0; /* false */ + data = CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_goodG2B1Source(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcscat(data, source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_goodG2B2Source(wchar_t * data); + +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_goodG2B2Global = 1; /* true */ + data = CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_goodG2B2Source(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcscat(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_07.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_07_bad() +{ + char * data; + data = NULL; + if(staticFive==5) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(staticFive==5) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_16_bad() +{ + char * data; + data = NULL; + while(1) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + break; + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + data = NULL; + while(1) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + break; + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_42.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_42.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: swprintf + * BadSink : Copy string to data using swprintf + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +static wchar_t * badSource(wchar_t * data) +{ + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_42_bad() +{ + wchar_t * data; + data = NULL; + data = badSource(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static wchar_t * goodG2BSource(wchar_t * data) +{ + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + data = goodG2BSource(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L""%s"", source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54c_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54b_badSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54b_goodG2BSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_61b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_61b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_61b_badSource(wchar_t * data) +{ + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_61b_goodG2BSource(wchar_t * data) +{ + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_18.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_18.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_18_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + goto source; +source: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + goto source; +source: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + size_t i, dataLen; + dataLen = strlen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_09.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_09.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_09_bad() +{ + char * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_32.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_32.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-32.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_32_bad() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + { + char * data = *dataPtr1; + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + { + char * data = *dataPtr1; + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_32_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sink: + * BadSink : Print then free data + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52b_badSink(int64_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52_bad() +{ + int64_t * data; + /* Initialize data */ + data = NULL; + /* INCIDENTAL: CWE-467 (Use of sizeof() on a pointer type) */ + /* FLAW: Using sizeof the pointer and not the data type in malloc() */ + data = (int64_t *)malloc(sizeof(data)); + *data = 2147483643LL; + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52b_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int64_t * data; + /* Initialize data */ + data = NULL; + /* FIX: Using sizeof the data type in malloc() */ + data = (int64_t *)malloc(sizeof(*data)); + *data = 2147483643LL; + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_int64_t_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_12.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_12_bad() +{ + char * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_61b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_61b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +char * CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_61b_badSource(char * data) +{ + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +char * CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_61b_goodG2BSource(char * data) +{ + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_03.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_03.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_03_bad() +{ + int * data; + data = NULL; + if(5==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(5==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_42.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_42.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-42.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 42 Data flow: data returned from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +static char * badSource(char * data) +{ + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_42_bad() +{ + char * data; + data = NULL; + data = badSource(data); + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static char * goodG2BSource(char * data) +{ + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + return data; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + data = goodG2BSource(data); + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_42_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_42_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_42_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_12_bad() +{ + wchar_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_17.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_17.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_17_bad() +{ + int i; + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + for(i = 0; i < 1; i++) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + for(h = 0; h < 1; h++) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53d_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53d_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_structType +{ + char * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_structType myStruct); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_bad() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_structType myStruct; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_structType myStruct; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67b_goodG2BSink(myStruct); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_09.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_09.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_09_bad() +{ + twoIntsStruct * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + twoIntsStruct * data; + data = NULL; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_51b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_51b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_51b_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_51b_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_structType +{ + wchar_t * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_structType myStruct); + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_bad() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_structType myStruct; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_structType myStruct); + +static void goodG2B() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_structType myStruct; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67b_goodG2BSink(myStruct); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_32.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_32.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-32.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: large Large index value that is greater than 10-1 + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 32 Data flow using two pointers to the same value within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_32_bad() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + int *dataPtr1 = &data; + int *dataPtr2 = &data; + /* Initialize data */ + data = -1; + { + int data = *dataPtr1; + /* POTENTIAL FLAW: Use an invalid index */ + data = 10; + *dataPtr1 = data; + } + { + int data = *dataPtr2; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_32_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_32_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_32_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_67b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_67b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_67_structType +{ + twoIntsStruct * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_67_structType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_67_structType myStruct) +{ + twoIntsStruct * data = myStruct.structFirst; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_67_structType myStruct) +{ + twoIntsStruct * data = myStruct.structFirst; + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + free(data); + } + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52c_badSink(twoIntsStruct * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52b_badSink(twoIntsStruct * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52c_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52b_goodG2BSink(twoIntsStruct * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63b_badSink(char * * dataPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63b_goodG2BSink(char * * data); + +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_63b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_63b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-63b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_63b_badSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_63b_goodG2BSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_63b_goodB2GSink(int * dataPtr) +{ + int data = *dataPtr; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_09.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_09.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-09.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_09_bad() +{ + char * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the GLOBAL_CONST_TRUE to GLOBAL_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(GLOBAL_CONST_TRUE) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_09_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_06_bad() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_53d_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_53d_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34_unionType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34_bad() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34_unionType myUnion; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34_unionType myUnion; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_67b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_67b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_67_structType +{ + wchar_t * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_67_structType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_67_structType myStruct) +{ + wchar_t * data = myStruct.structFirst; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_07.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_07_bad() +{ + wchar_t * data; + data = NULL; + if(staticFive==5) + { + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(staticFive==5) + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-41.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using strncpy() + * Flow Variant: 41 Data flow: data passed as an argument from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41_badSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41_bad() +{ + char * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41_goodG2BSink(char * data) +{ + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strncpy(data, source, strlen(source) + 1); + printLine(data); + free(data); + } +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_ncpy_41_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_53c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_53c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_53d_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_53c_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_53d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_53c_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_17.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_17.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_17_bad() +{ + int i; + int * data; + data = NULL; + for(i = 0; i < 1; i++) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + int * data; + data = NULL; + for(h = 0; h < 1; h++) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + char * unionFirst; + char * unionSecond; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34_unionType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34_bad() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34_unionType myUnion; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34_unionType myUnion; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + myUnion.unionFirst = data; + { + char * data = myUnion.unionSecond; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_63b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_63b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-63b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_63b_badSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_63b_goodG2BSink(char * * dataPtr) +{ + char * data = *dataPtr; + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_18.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_18.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_18_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + goto source; +source: + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + goto source; +source: + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_10.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_10.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_10_bad() +{ + twoIntsStruct * data; + data = NULL; + if(globalTrue) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + twoIntsStruct * data; + data = NULL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + twoIntsStruct * data; + data = NULL; + if(globalTrue) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53b_badSink(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53_bad() +{ + int * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53b_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_03.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_03.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_03_bad() +{ + char * data; + data = NULL; + if(5==5) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(5==5) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-34.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 34 Data flow: use of a union containing two methods of accessing the same data (within the same function) + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef union +{ + wchar_t * unionFirst; + wchar_t * unionSecond; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34_unionType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34_bad() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34_unionType myUnion; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34_unionType myUnion; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + myUnion.unionFirst = data; + { + wchar_t * data = myUnion.unionSecond; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_34_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53c_badSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53b_badSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53c_goodG2BSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53b_goodG2BSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53c_goodB2GSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53b_goodB2GSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_53c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53c_badSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53b_badSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53c_goodG2BSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53b_goodG2BSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53c_goodB2GSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53b_goodB2GSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_53c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_53d_badSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_53d_goodG2BSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_11.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_11.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-11.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_11_bad() +{ + int * data; + data = NULL; + if(globalReturnsTrue()) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(globalReturnsTrue()) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_11_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_52c_badSink(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_52b_badSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_52c_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_52b_goodG2BSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53d_badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53d_goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_52c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_52c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_52c_badSink(wchar_t * data) +{ + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_52c_goodG2BSink(wchar_t * data) +{ + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51b_badSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_51b_goodG2BSink(char * data) +{ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_07.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_07_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_09.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_09.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-09.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memcpy + * GoodSink: Perform the memcpy() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memcpy() + * Flow Variant: 09 Control flow: if(GLOBAL_CONST_TRUE) and if(GLOBAL_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR L""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + wchar_t charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_09_bad() +{ + if(GLOBAL_CONST_TRUE) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + free(structCharVoid); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(GLOBAL_CONST_FALSE) instead of if(GLOBAL_CONST_TRUE) */ +static void good1() +{ + if(GLOBAL_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + free(structCharVoid); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(GLOBAL_CONST_TRUE) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printWLine((wchar_t *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(wchar_t))-1] = L'\0'; /* null terminate the string */ + printWLine((wchar_t *)structCharVoid->charFirst); + printWLine((wchar_t *)structCharVoid->voidSecond); + free(structCharVoid); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_09_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_09_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__wchar_t_type_overrun_memcpy_09_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_21.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_21.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static int64_t * badSource(int64_t * data) +{ + if(badStatic) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_21_bad() +{ + int64_t * data; + data = NULL; + badStatic = 1; /* true */ + data = badSource(data); + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static int64_t * goodG2B1Source(int64_t * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +static void goodG2B1() +{ + int64_t * data; + data = NULL; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static int64_t * goodG2B2Source(int64_t * data) +{ + if(goodG2B2Static) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + return data; +} + +static void goodG2B2() +{ + int64_t * data; + data = NULL; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy twoIntsStruct array to data using memmove + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_16_bad() +{ + twoIntsStruct * data; + data = NULL; + while(1) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (twoIntsStruct *)malloc(50*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + break; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + twoIntsStruct * data; + data = NULL; + while(1) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (twoIntsStruct *)malloc(100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + break; + } + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(twoIntsStruct)); + printStructLine(&data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memmove_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_badSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52b_badSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_goodG2BSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52b_goodG2BSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_goodB2GSink(int data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52b_goodB2GSink(int data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_16_bad() +{ + int * data; + data = NULL; + while(1) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + break; + } + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + int * data; + data = NULL; + while(1) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + break; + } + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_52c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_52c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-52c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_52c_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_52c_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sinks: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int * CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61b_badSource(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61_bad() +{ + int * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61b_badSource(data); + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int * CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61b_goodG2BSource(int * data); + +static void goodG2B() +{ + int * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61b_goodG2BSource(data); + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64b_badSink(void * dataVoidPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64_bad() +{ + char * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_54c_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_54b_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_54b_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memmove_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using wcscpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_53d_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cpy_53d_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcscpy(dest, data); + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: snprintf + * BadSink : Copy data to string using snprintf + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_08_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticReturnsTrue()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticReturnsTrue()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, strlen(data), ""%s"", data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_snprintf_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_51b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_51b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_51b_badSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_51b_goodG2BSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68_badData; +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68b_badSink(); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68_badData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68_goodG2BData = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68b_goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_double_64b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_double_64b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sinks: + * BadSink : Print then free data + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_double_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + double * * dataPtr = (double * *)dataVoidPtr; + /* dereference dataPtr into data */ + double * data = (*dataPtr); + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printDoubleLine(*data); + free(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_double_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + double * * dataPtr = (double * *)dataVoidPtr; + /* dereference dataPtr into data */ + double * data = (*dataPtr); + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printDoubleLine(*data); + free(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_67b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_67b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-67b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_67_structType +{ + char * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_67_structType; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_67_structType myStruct) +{ + char * data = myStruct.structFirst; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strcpy(dest, data); + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_06_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_13.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_13.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-13.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_13_bad() +{ + if(GLOBAL_CONST_FIVE==5) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses if(GLOBAL_CONST_FIVE!=5) instead of if(GLOBAL_CONST_FIVE==5) */ +static void good1() +{ + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } +} + +/* good2() reverses the bodies in the if statement */ +static void good2() +{ + if(GLOBAL_CONST_FIVE==5) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_13_good() +{ + good1(); + good2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_31.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_31.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_31_bad() +{ + int data; + /* Initialize data */ + data = -1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_52c_badSink(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_52b_badSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_52c_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_52b_goodG2BSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_04.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_04.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_04_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_TRUE) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_TRUE) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-45.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sinks: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 45 Data flow: data passed as a static global variable from one function to another in the same source file + * + * */ + +#include ""std_testcase.h"" + +static int * CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_badData; +static int * CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_goodG2BData; + +#ifndef OMITBAD + +static void badSink() +{ + int * data = CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_badData; + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_bad() +{ + int * data; + data = NULL; + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_badData = data; + badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink() +{ + int * data = CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_goodG2BData; + { + int source[10] = {0}; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + } + printIntLine(data[0]); + free(data); + } +} + +static void goodG2B() +{ + int * data; + data = NULL; + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_goodG2BData = data; + goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_45_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_05_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + if(staticTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-64a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snprintf +#else +#define SNPRINTF snprintf +#endif + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64b_badSink(void * dataVoidPtr); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64b_goodG2BSink(void * dataVoidPtr); + +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_snprintf_64_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_66b_badSink(int64_t * dataArray[]) +{ + /* copy data out of dataArray */ + int64_t * data = dataArray[2]; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_66b_goodG2BSink(int64_t * dataArray[]) +{ + int64_t * data = dataArray[2]; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_05_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_54c_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_54b_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_54c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_54b_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_05_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticTrue) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticTrue) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_06_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_11.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_11.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-11.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 11 Control flow: if(globalReturnsTrue()) and if(globalReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_11_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalReturnsTrue() to globalReturnsFalse() */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalReturnsTrue()) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalReturnsTrue()) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_11_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_11_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_11_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_68b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_68b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +extern int64_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_68_badData; +extern int64_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_68b_badSink() +{ + int64_t * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_68_badData; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_68b_goodG2BSink() +{ + int64_t * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_68_goodG2BData; + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-22b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_badGlobal; + +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_badSource(char * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_badGlobal) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_goodG2B1Global; +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_goodG2B2Global; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_goodG2B1Source(char * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_goodG2B1Global) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_goodG2B2Source(char * data) +{ + if(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_22_goodG2B2Global) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_16.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_16.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-16.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 16 Control flow: while(1) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_16_bad() +{ + char * data; + data = NULL; + while(1) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + break; + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ +static void goodG2B() +{ + char * data; + data = NULL; + while(1) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + break; + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_16_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_16_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_16_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-68b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68_badData; +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68_goodG2BData; +extern int CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68_goodB2GData; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68b_badSink() +{ + int data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68_badData; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68b_goodG2BSink() +{ + int data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68_goodG2BData; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68b_goodB2GSink() +{ + int data = CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_68_goodB2GData; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_54d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_54d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-54d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_54e_badSink(void * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_54d_badSink(void * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE135_54e_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_54e_goodG2BSink(void * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_54d_goodG2BSink(void * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE135_54e_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_54e_goodB2GSink(void * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_54d_goodB2GSink(void * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE135_54e_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_03.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_03.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_03_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(5==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(5==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + wcsncpy(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_08_bad() +{ + char * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memcpy(data, source, (strlen(source) + 1) * sizeof(char)); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_64b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_64b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-64b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 64 Data flow: void pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_64b_badSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_64b_goodG2BSink(void * dataVoidPtr) +{ + /* cast void pointer to a pointer of the appropriate type */ + wchar_t * * dataPtr = (wchar_t * *)dataVoidPtr; + /* dereference dataPtr into data */ + wchar_t * data = (*dataPtr); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_66b_badSink(wchar_t * dataArray[]) +{ + /* copy data out of dataArray */ + wchar_t * data = dataArray[2]; + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_loop_66b_goodG2BSink(wchar_t * dataArray[]) +{ + wchar_t * data = dataArray[2]; + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: swprintf + * BadSink : Copy data to string using swprintf + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF swprintf +#endif + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_12_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(globalReturnsTrueOrFalse()) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + SNPRINTF(dest, wcslen(data), L""%s"", data); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_snprintf_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_14_bad() +{ + int64_t * data; + data = NULL; + if(globalFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int64_t * data; + data = NULL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int64_t * data; + data = NULL; + if(globalFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_05.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_05_bad() +{ + char * data; + data = NULL; + if(staticTrue) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(staticTrue) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_07.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_07_bad() +{ + char * data; + data = NULL; + if(staticFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(staticFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy twoIntsStruct array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54e_badSink(twoIntsStruct * data) +{ + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_54e_goodG2BSink(twoIntsStruct * data) +{ + { + twoIntsStruct source[100]; + { + size_t i; + /* Initialize array */ + for (i = 0; i < 100; i++) + { + source[i].intOne = 0; + source[i].intTwo = 0; + } + } + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printStructLine(&data[0]); + free(data); + } + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_54e_badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_54e_goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_13.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_13.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_13_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET connectSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + recvResult = recv(connectSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-68b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_badData; +extern char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_goodG2BData; + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68b_badSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_badData; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68b_goodG2BSink() +{ + char * data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memmove_68_goodG2BData; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_structType +{ + char * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_structType myStruct); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_bad() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_structType myStruct; + data = (char *)malloc(100*sizeof(char)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_structType myStruct; + data = (char *)malloc(100*sizeof(char)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67b_goodG2BSink(myStruct); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_loop_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_12.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow.label.xml +Template File: point-flaw-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * Sinks: type_overrun_memmove + * GoodSink: Perform the memmove() and prevent overwriting part of the structure + * BadSink : Overwrite part of the structure by incorrectly using the sizeof(struct) in memmove() + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +#define SRC_STR ""0123456789abcdef0123456789abcde"" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_12_bad() +{ + if(globalReturnsTrueOrFalse()) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good1() uses the GoodSink on both sides of the ""if"" statement */ +static void good1() +{ + if(globalReturnsTrueOrFalse()) + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } + else + { + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + if (structCharVoid == NULL) {exit(-1);} + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FIX: Use the sizeof(structCharVoid->charFirst) to avoid overwriting the pointer y */ + memmove(structCharVoid->charFirst, SRC_STR, sizeof(structCharVoid->charFirst)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_12_good() +{ + good1(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memmove_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_53d.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_53d.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-53d.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int64_t array to data using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_53d_badSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_loop_53d_goodG2BSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + printLongLongLine(data[0]); + free(data); + } + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_21.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_21.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static char * badSource(char * data) +{ + if(badStatic) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_21_bad() +{ + char * data; + data = NULL; + badStatic = 1; /* true */ + data = badSource(data); + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static char * goodG2B1Source(char * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + return data; +} + +static void goodG2B1() +{ + char * data; + data = NULL; + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static char * goodG2B2Source(char * data) +{ + if(goodG2B2Static) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + return data; +} + +static void goodG2B2() +{ + char * data; + data = NULL; + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + char source[10+1] = SRC_STRING; + size_t i, sourceLen; + sourceLen = strlen(source); + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + for (i = 0; i < sourceLen + 1; i++) + { + data[i] = source[i]; + } + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_loop_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using wcsncat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_54e_badSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncat_54e_goodG2BSink(wchar_t * data) +{ + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-wcslen(dest)*/ + wcsncat(dest, data, wcslen(data)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_07.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_07_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(staticFive==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memcpy_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-54c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54d_badSink(int64_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54c_badSink(int64_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54d_goodG2BSink(int64_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54c_goodG2BSink(int64_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_54d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_18.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_18.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-18.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_18_bad() +{ + int data; + /* Initialize data */ + data = -1; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goto sink; +sink: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + goto source; +source: + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + goto sink; +sink: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the first goto statement */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + goto source; +source: + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + goto sink; +sink: + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_18_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-68a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 68 Data flow: data passed as a global variable from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68_badData; +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68_goodG2BData; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68b_badSink(); + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68_badData = data; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68b_badSink(); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68b_goodG2BSink(); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68_goodG2BData = data; + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68b_goodG2BSink(); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_68_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_54c_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_54b_badSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_54b_goodG2BSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: loop + * BadSink : Copy data to string using a loop + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_06_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(STATIC_CONST_FIVE==5) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + size_t i, dataLen; + dataLen = wcslen(data); + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < dataLen; i++) + { + dest[i] = data[i]; + } + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_loop_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_10.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_10.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-10.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using strcpy + * Flow Variant: 10 Control flow: if(globalTrue) and if(globalFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_10_bad() +{ + char * data; + data = NULL; + if(globalTrue) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalTrue to globalFalse */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(globalFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(globalTrue) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_10_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_10_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cpy_10_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-66a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66b_badSink(char * dataArray[]); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66_bad() +{ + char * data; + char * dataArray[5]; + data = (char *)malloc(100*sizeof(char)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* put data in array */ + dataArray[2] = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66b_badSink(dataArray); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66b_goodG2BSink(char * dataArray[]); + +static void goodG2B() +{ + char * data; + char * dataArray[5]; + data = (char *)malloc(100*sizeof(char)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + dataArray[2] = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66b_goodG2BSink(dataArray); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memmove_66_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_65b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_65b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-65b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memmove + * BadSink : Copy int64_t array to data using memmove + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_65b_badSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memmove_65b_goodG2BSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cat + * BadSink : Copy data to string using wcscat + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_wchar_t_cat_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_12.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_12_bad() +{ + wchar_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memcpy + * BadSink : Copy string to data using memcpy() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52_bad() +{ + char * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_memcpy_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-65a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65b_badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65b_goodG2BSink(char * data); + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65b_goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: large Large index value that is greater than 10-1 + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_66b_badSink(int dataArray[]) +{ + /* copy data out of dataArray */ + int data = dataArray[2]; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_66b_goodG2BSink(int dataArray[]) +{ + int data = dataArray[2]; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_large_66b_goodB2GSink(int dataArray[]) +{ + int data = dataArray[2]; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_15.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_15.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-15.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 15 Control flow: switch(6) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_15_bad() +{ + int * data; + data = NULL; + switch(6) + { + case 6: + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the switch to switch(5) */ +static void goodG2B1() +{ + int * data; + data = NULL; + switch(5) + { + case 6: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + default: + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + break; + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the switch */ +static void goodG2B2() +{ + int * data; + data = NULL; + switch(6) + { + case 6: + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + break; + default: + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + break; + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_15_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_15_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_15_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_03.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_03.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-03.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_03_bad() +{ + char * data; + data = NULL; + if(5==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(5==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_03_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fscanf Read data from the console using fscanf() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is declared ""const"", so a tool should be able + to identify that reads of this will always give its initialized + value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_06_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, ""%d"", &data); + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(STATIC_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_06_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_06_bad() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_01.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_01.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using strncpy + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_01_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + strncpy(data, source, 100-1); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncpy_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_52c_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_52b_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_52c_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_52b_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_52c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-54a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54b_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54b_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + data[0] = '\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_54_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_05.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_05.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-05.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using wcsncat + * Flow Variant: 05 Control flow: if(staticTrue) and if(staticFalse) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are not defined as ""const"", but are never + * assigned any other value, so a tool should be able to identify that + * reads of these will always return their initialized values. + */ +static int staticTrue = 1; /* true */ +static int staticFalse = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_05_bad() +{ + wchar_t * data; + data = NULL; + if(staticTrue) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticTrue to staticFalse */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(staticFalse) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(staticTrue) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcsncat(data, source, 100); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_05_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_05_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncat_05_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_17.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_17.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_17_bad() +{ + int i; + wchar_t * data; + data = NULL; + for(i = 0; i < 1; i++) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + wchar_t * data; + data = NULL; + for(h = 0; h < 1; h++) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcscpy(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_structType +{ + char * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_structType myStruct); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_bad() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_structType myStruct; + data = (char *)malloc(100*sizeof(char)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_structType myStruct); + +static void goodG2B() +{ + char * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_structType myStruct; + data = (char *)malloc(100*sizeof(char)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67b_goodG2BSink(myStruct); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncat + * BadSink : Copy data to string using strncat + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strncat(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncat_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_13.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_13.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-13.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 13 Control flow: if(GLOBAL_CONST_FIVE==5) and if(GLOBAL_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_13_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first GLOBAL_CONST_FIVE==5 to GLOBAL_CONST_FIVE!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(GLOBAL_CONST_FIVE==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(GLOBAL_CONST_FIVE==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_13_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_13_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_13_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_14_bad() +{ + wchar_t * data; + data = NULL; + if(globalFive==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(globalFive==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_14_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_18.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_18.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-18.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using strcat + * Flow Variant: 18 Control flow: goto statements + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_18_bad() +{ + char * data; + data = NULL; + goto source; +source: + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by reversing the blocks on the goto statement */ +static void goodG2B() +{ + char * data; + data = NULL; + goto source; +source: + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_18_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_18_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_18_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy int array to data using a loop + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53c_badSink(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53b_badSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53c_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53b_goodG2BSink(int * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_loop_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_31.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_31.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-31.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_31_bad() +{ + char * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + { + char * dataCopy = data; + char * data = dataCopy; + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + { + char * dataCopy = data; + char * data = dataCopy; + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_31_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-53b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy twoIntsStruct array to data using memcpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53c_badSink(twoIntsStruct * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53b_badSink(twoIntsStruct * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53c_goodG2BSink(twoIntsStruct * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53b_goodG2BSink(twoIntsStruct * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_memcpy_53c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-63a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sinks: + * BadSink : Print then free data + * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63b_badSink(twoIntsStruct * * dataPtr); + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63_bad() +{ + twoIntsStruct * data; + /* Initialize data */ + data = NULL; + /* INCIDENTAL: CWE-467 (Use of sizeof() on a pointer type) */ + /* FLAW: Using sizeof the pointer and not the data type in malloc() */ + data = (twoIntsStruct *)malloc(sizeof(data)); + data->intOne = 1; + data->intTwo = 2; + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63b_badSink(&data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63b_goodG2BSink(twoIntsStruct * * data); + +static void goodG2B() +{ + twoIntsStruct * data; + /* Initialize data */ + data = NULL; + /* FIX: Using sizeof the data type in malloc() */ + data = (twoIntsStruct *)malloc(sizeof(*data)); + data->intOne = 1; + data->intTwo = 2; + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63b_goodG2BSink(&data); +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_struct_63_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_17.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_17.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-17.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_17_bad() +{ + int i,j; + int data; + /* Initialize data */ + data = -1; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + for(j = 0; j < 1; j++) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G() - use badsource and goodsink in the for statements */ +static void goodB2G() +{ + int i,k; + int data; + /* Initialize data */ + data = -1; + for(i = 0; i < 1; i++) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + for(k = 0; k < 1; k++) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B() - use goodsource and badsink in the for statements */ +static void goodG2B() +{ + int h,j; + int data; + /* Initialize data */ + data = -1; + for(h = 0; h < 1; h++) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + for(j = 0; j < 1; j++) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_17_good() +{ + goodB2G(); + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-67a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: snprintf + * BadSink : Copy string to data using snprintf + * Flow Variant: 67 Data flow: data passed in a struct from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifdef _WIN32 +#define SNPRINTF _snwprintf +#else +#define SNPRINTF snprintf +#endif + +typedef struct _CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_structType +{ + wchar_t * structFirst; +} CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_structType; + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67b_badSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_structType myStruct); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_bad() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_structType myStruct; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67b_badSink(myStruct); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67b_goodG2BSink(CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_structType myStruct); + +static void goodG2B() +{ + wchar_t * data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_structType myStruct; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + myStruct.structFirst = data; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67b_goodG2BSink(myStruct); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_snprintf_67_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: ncpy + * BadSink : Copy data to string using wcsncpy + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_ncpy_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__sizeof_double_07.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__sizeof_double_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__sizeof.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize the source buffer using the size of a pointer + * GoodSource: Initialize the source buffer using the size of the DataElementType + * Sink: + * BadSink : Print then free data + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_double_07_bad() +{ + double * data; + /* Initialize data */ + data = NULL; + if(staticFive==5) + { + /* INCIDENTAL: CWE-467 (Use of sizeof() on a pointer type) */ + /* FLAW: Using sizeof the pointer and not the data type in malloc() */ + data = (double *)malloc(sizeof(data)); + if (data == NULL) {exit(-1);} + *data = 1.7E300; + } + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printDoubleLine(*data); + free(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + double * data; + /* Initialize data */ + data = NULL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Using sizeof the data type in malloc() */ + data = (double *)malloc(sizeof(*data)); + if (data == NULL) {exit(-1);} + *data = 1.7E300; + } + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printDoubleLine(*data); + free(data); +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + double * data; + /* Initialize data */ + data = NULL; + if(staticFive==5) + { + /* FIX: Using sizeof the data type in malloc() */ + data = (double *)malloc(sizeof(*data)); + if (data == NULL) {exit(-1);} + *data = 1.7E300; + } + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printDoubleLine(*data); + free(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_double_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_double_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__sizeof_double_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_31.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_31.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-31.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 31 Data flow using a copy of data within the same function + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_31_bad() +{ + int data; + /* Initialize data */ + data = -1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int data; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + { + int dataCopy = data; + int data = dataCopy; + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_31_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_31_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_31_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: listen_socket Read data using a listen socket (server side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define LISTEN_BACKLOG 5 +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_14_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + SOCKET listenSocket = INVALID_SOCKET; + SOCKET acceptSocket = INVALID_SOCKET; + char inputBuffer[CHAR_ARRAY_SIZE]; + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a listen socket */ + listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listenSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = INADDR_ANY; + service.sin_port = htons(TCP_PORT); + if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) + { + break; + } + acceptSocket = accept(listenSocket, NULL, NULL); + if (acceptSocket == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed */ + recvResult = recv(acceptSocket, inputBuffer, CHAR_ARRAY_SIZE - 1, 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* NUL-terminate the string */ + inputBuffer[recvResult] = '\0'; + /* Convert to int */ + data = atoi(inputBuffer); + } + while (0); + if (listenSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(listenSocket); + } + if (acceptSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(acceptSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + } + if(globalFive==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalFive==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalFive==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_listen_socket_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: cat + * BadSink : Copy data to string using strcat + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_44_bad() +{ + char * data; + /* define a function pointer */ + void (*funcPtr) (char *) = badSink; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(char * data) +{ + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than sizeof(dest)-strlen(dest)*/ + strcat(dest, data); + printLine(data); + free(data); + } +} + +static void goodG2B() +{ + char * data; + void (*funcPtr) (char *) = goodG2BSink; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cat_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_21.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_21.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-21.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memcpy + * BadSink : Copy data to string using memcpy + * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static char * badSource(char * data) +{ + if(badStatic) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + memset(data, 'A', 100-1); /* fill with 'A's */ + data[100-1] = '\0'; /* null terminate */ + } + return data; +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_21_bad() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + badStatic = 1; /* true */ + data = badSource(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The static variables below are used to drive control flow in the source functions. */ +static int goodG2B1Static = 0; +static int goodG2B2Static = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +static char * goodG2B1Source(char * data) +{ + if(goodG2B1Static) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +static void goodG2B1() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + goodG2B1Static = 0; /* false */ + data = goodG2B1Source(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +static char * goodG2B2Source(char * data) +{ + if(goodG2B2Static) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + memset(data, 'A', 50-1); /* fill with 'A's */ + data[50-1] = '\0'; /* null terminate */ + } + return data; +} + +static void goodG2B2() +{ + char * data; + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + goodG2B2Static = 1; /* true */ + data = goodG2B2Source(data); + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memcpy(dest, data, strlen(data)*sizeof(char)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_21_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_21_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_memcpy_21_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-53a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + data[0] = L'\0'; /* null terminate */ + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_53_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cat + * BadSink : Copy string to data using wcscat + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_06_bad() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcscat(data, source); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcscat(data, source); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + } + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + wcscat(data, source); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cat_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: ncpy + * BadSink : Copy string to data using wcsncpy + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_ncpy_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_51b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_51b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-51b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_51b_badSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_51b_goodG2BSink(int64_t * data) +{ + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_03.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_03.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-03.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 03 Control flow: if(5==5) and if(5!=5) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_03_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second 5==5 to 5!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(5==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first 5==5 to 5!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(5!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(5==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(5==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(5==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_03_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_03_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_03_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_02.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_02.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-02.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: memmove + * BadSink : Copy data to string using memmove + * Flow Variant: 02 Control flow: if(1) and if(0) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_02_bad() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(1) + { + /* FLAW: Initialize data as a large buffer that is larger than the small buffer used in the sink */ + wmemset(data, L'A', 100-1); /* fill with L'A's */ + data[100-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ +static void goodG2B1() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(0) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + if(1) + { + /* FIX: Initialize data as a small buffer that as small or smaller than the small buffer used in the sink */ + wmemset(data, L'A', 50-1); /* fill with L'A's */ + data[50-1] = L'\0'; /* null terminate */ + } + { + wchar_t dest[50] = L""""; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + memmove(dest, data, wcslen(data)*sizeof(wchar_t)); + dest[50-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_02_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_02_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE806_wchar_t_memmove_02_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_06_bad() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + } + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61b_badSource(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61_bad() +{ + char * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61b_badSource(data); + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +char * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61b_goodG2BSource(char * data); + +static void goodG2B() +{ + char * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61b_goodG2BSource(data); + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_44_bad() +{ + int * data; + /* define a function pointer */ + void (*funcPtr) (int *) = badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int *)malloc(50*sizeof(int)); + if (data == NULL) {exit(-1);} + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +static void goodG2B() +{ + int * data; + void (*funcPtr) (int *) = goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int *)malloc(100*sizeof(int)); + if (data == NULL) {exit(-1);} + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_54e.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_54e.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-54e.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy int array to data using memmove + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_54e_badSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memmove_54e_goodG2BSink(int * data) +{ + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memmove(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_08.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_08.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-08.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 08 Control flow: if(staticReturnsTrue()) and if(staticReturnsFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two function below always return the same value, so a tool + * should be able to identify that calls to the functions will always + * return a fixed value. + */ +static int staticReturnsTrue() +{ + return 1; +} + +static int staticReturnsFalse() +{ + return 0; +} + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_08_bad() +{ + char * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticReturnsTrue() to staticReturnsFalse() */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(staticReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(staticReturnsTrue()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_08_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_08_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_08_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_04.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_04.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-04.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#include + +/* The two variables below are declared ""const"", so a tool should + * be able to identify that reads of these will always return their + * initialized values. + */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_04_bad() +{ + char * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(STATIC_CONST_TRUE) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_04_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-54b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: loop + * BadSink : Copy array to data using a loop + * Flow Variant: 54 Data flow: data passed as an argument from one function through three others to a fifth; all five functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54c_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54b_badSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54c_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54b_goodG2BSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_loop_54c_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_65a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_65a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-65a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 65 Data/control flow: data passed as an argument from one function to a function in a different source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_65b_badSink(void * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_65_bad() +{ + void * data; + /* define a function pointer */ + void (*funcPtr) (void *) = CWE122_Heap_Based_Buffer_Overflow__CWE135_65b_badSink; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_65b_goodG2BSink(void * data); + +static void goodG2B() +{ + void * data; + void (*funcPtr) (void *) = CWE122_Heap_Based_Buffer_Overflow__CWE135_65b_goodG2BSink; + data = NULL; + { + char * dataGoodBuffer = (char *)malloc(50*sizeof(char)); + if (dataGoodBuffer == NULL) {exit(-1);} + memset(dataGoodBuffer, 'A', 50-1); + dataGoodBuffer[50-1] = '\0'; + /* FIX: Set data to point to a char string */ + data = (void *)dataGoodBuffer; + } + funcPtr(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_65b_goodB2GSink(void * data); + +static void goodB2G() +{ + void * data; + void (*funcPtr) (void *) = CWE122_Heap_Based_Buffer_Overflow__CWE135_65b_goodB2GSink; + data = NULL; + { + wchar_t * dataBadBuffer = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (dataBadBuffer == NULL) {exit(-1);} + wmemset(dataBadBuffer, L'A', 50-1); + dataBadBuffer[50-1] = L'\0'; + /* POTENTIAL FLAW: Set data to point to a wide string */ + data = (void *)dataBadBuffer; + } + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_65_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_65_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE135_65_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-22a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memmove + * BadSink : Copy string to data using memmove + * Flow Variant: 22 Control flow: Flow controlled by value of a global variable. Sink functions are in a separate file from sources. + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* The global variable below is used to drive control flow in the source function */ +int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_badGlobal = 0; + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_badSource(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_bad() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_badGlobal = 1; /* true */ + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_badSource(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* The global variables below are used to drive control flow in the source functions. */ +int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_goodG2B1Global = 0; +int CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_goodG2B2Global = 0; + +/* goodG2B1() - use goodsource and badsink by setting the static variable to false instead of true */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_goodG2B1Source(wchar_t * data); + +static void goodG2B1() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_goodG2B1Global = 0; /* false */ + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_goodG2B1Source(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if in the source function */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_goodG2B2Source(wchar_t * data); + +static void goodG2B2() +{ + wchar_t * data; + data = NULL; + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_goodG2B2Global = 1; /* true */ + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_goodG2B2Source(data); + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memmove(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memmove_22_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_52c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_52c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-52c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: connect_socket Read data using a connect socket (client side) + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, ""ws2_32"") /* include ws2_32.lib when linking */ +#define CLOSE_SOCKET closesocket +#else /* NOT _WIN32 */ +#include +#include +#include +#include +#include +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define CLOSE_SOCKET close +#define SOCKET int +#endif + +#define TCP_PORT 27015 +#define IP_ADDRESS ""127.0.0.1"" +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_52c_badSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_52c_goodG2BSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_connect_socket_52c_goodB2GSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE135_52b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE135_52b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE135.label.xml +Template File: sources-sinks-52b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Void pointer to a wchar_t array + * GoodSource: Void pointer to a char array + * Sinks: + * GoodSink: Allocate memory using wcslen() and copy data + * BadSink : Allocate memory using strlen() and copy data + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_52c_badSink(void * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_52b_badSink(void * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE135_52c_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_52c_goodG2BSink(void * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_52b_goodG2BSink(void * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE135_52c_goodG2BSink(data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +void CWE122_Heap_Based_Buffer_Overflow__CWE135_52c_goodB2GSink(void * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE135_52b_goodB2GSink(void * data) +{ + CWE122_Heap_Based_Buffer_Overflow__CWE135_52c_goodB2GSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-61a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy int array to data using memcpy + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +int * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61b_badSource(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61_bad() +{ + int * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61b_badSource(data); + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +int * CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61b_goodG2BSource(int * data); + +static void goodG2B() +{ + int * data; + data = NULL; + data = CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61b_goodG2BSource(data); + { + int source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int_memcpy_61_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_dest.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: cpy + * BadSink : Copy string to data using wcscpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53d_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53c_badSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53d_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53c_goodG2BSink(wchar_t * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_dest_wchar_t_cpy_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +static void badSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_44_bad() +{ + int data; + /* define a function pointer */ + void (*funcPtr) (int) = badSink; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } +} + +static void goodG2B() +{ + int data; + void (*funcPtr) (int) = goodG2BSink; + /* Initialize data */ + data = -1; + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + funcPtr(data); +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void goodB2GSink(int data) +{ + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } +} + +static void goodB2G() +{ + int data; + void (*funcPtr) (int) = goodB2GSink; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_44_good() +{ + goodG2B(); + goodB2G(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_53c.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_53c.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_src.label.xml +Template File: sources-sink-53c.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sink: cpy + * BadSink : Copy data to string using strcpy + * Flow Variant: 53 Data flow: data passed as an argument from one function through two others to a fourth; all four functions are in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +/* all the sinks are the same, we just want to know where the hit originated if a tool flags one */ + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_53d_badSink(char * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_53c_badSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_53d_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_53d_goodG2BSink(char * data); + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_53c_goodG2BSink(char * data) +{ + CWE122_Heap_Based_Buffer_Overflow__c_src_char_cpy_53d_goodG2BSink(data); +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_01.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_01.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 01 Baseline + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_01_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_01_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_01_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_61b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_61b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-61b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sinks: ncpy + * BadSink : Copy string to data using wcsncpy() + * Flow Variant: 61 Data flow: data returned from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_61b_badSource(wchar_t * data) +{ + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + return data; +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +wchar_t * CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_ncpy_61b_goodG2BSource(wchar_t * data) +{ + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + return data; +} + +#endif /* OMITGOOD */ +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_07.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_07.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-07.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memmove + * BadSink : Copy array to data using memmove() + * Flow Variant: 07 Control flow: if(staticFive==5) and if(staticFive!=5) + * + * */ + +#include ""std_testcase.h"" + +/* The variable below is not declared ""const"", but is never assigned + * any other value so a tool should be able to identify that reads of + * this will always give its initialized value. + */ +static int staticFive = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_07_bad() +{ + int * data; + data = NULL; + if(staticFive==5) + { + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the staticFive==5 to staticFive!=5 */ +static void goodG2B1() +{ + int * data; + data = NULL; + if(staticFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + int * data; + data = NULL; + if(staticFive==5) + { + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + if (data == NULL) {exit(-1);} + } + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memmove(data, source, 10*sizeof(int)); + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_07_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_07_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memmove_07_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_12.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: loop + * BadSink : Copy string to data using a loop + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_12_bad() +{ + char * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + char * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_loop_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml +Template File: sources-sink-51a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory without using sizeof(int) + * GoodSource: Allocate memory using sizeof(int) + * Sink: memcpy + * BadSink : Copy array to data using memcpy() + * Flow Variant: 51 Data flow: data passed as an argument from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51b_badSink(int * data); + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51_bad() +{ + int * data; + data = NULL; + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)malloc(10); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declarations */ +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51b_goodG2BSink(int * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + int * data; + data = NULL; + /* FIX: Allocate memory using sizeof(int) */ + data = (int *)malloc(10*sizeof(int)); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__CWE131_memcpy_51_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_04.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_04.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-04.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: fgets Read data from the console using fgets() + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 04 Control flow: if(STATIC_CONST_TRUE) and if(STATIC_CONST_FALSE) + * + * */ + +#include ""std_testcase.h"" + +#define CHAR_ARRAY_SIZE (3 * sizeof(data) + 2) + +/* The two variables below are declared ""const"", so a tool should + be able to identify that reads of these will always return their + initialized values. */ +static const int STATIC_CONST_TRUE = 1; /* true */ +static const int STATIC_CONST_FALSE = 0; /* false */ + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_04_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_TRUE) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_TRUE) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_TRUE) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_TRUE) + { + { + char inputBuffer[CHAR_ARRAY_SIZE] = """"; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine(""fgets() failed.""); + } + } + } + if(STATIC_CONST_TRUE) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_FALSE) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(STATIC_CONST_TRUE) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(STATIC_CONST_TRUE) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(STATIC_CONST_TRUE) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_04_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_04_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_04_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_14.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_14.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE129.label.xml +Template File: sources-sinks-14.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: rand Set data to result of rand(), which may be zero + * GoodSource: Larger than zero but less than 10 + * Sinks: + * GoodSink: Ensure the array index is valid + * BadSink : Improperly check the array index by not checking the upper bound + * Flow Variant: 14 Control flow: if(globalFive==5) and if(globalFive!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_14_bad() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalFive==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodB2G1() - use badsource and goodsink by changing the second globalFive==5 to globalFive!=5 */ +static void goodB2G1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ +static void goodB2G2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + } + if(globalFive==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* FIX: Properly validate the array index and prevent a buffer overflow */ + if (data >= 0 && data < (10)) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is out-of-bounds""); + } + free(buffer); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the first globalFive==5 to globalFive!=5 */ +static void goodG2B1() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalFive==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the first if */ +static void goodG2B2() +{ + int data; + /* Initialize data */ + data = -1; + if(globalFive==5) + { + /* FIX: Use a value greater than 0, but less than 10 to avoid attempting to + * access an index of the array in the sink that is out-of-bounds */ + data = 7; + } + if(globalFive==5) + { + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + if (buffer == NULL) {exit(-1);} + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine(""ERROR: Array index is negative.""); + } + free(buffer); + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_14_good() +{ + goodB2G1(); + goodB2G2(); + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + its own for testing or for building a binary to use in testing binary + analysis tools. It is not used when compiling all the testcases as one + application, which is how source code analysis tools are tested. */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_14_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_14_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_44.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_44.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-44.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sinks: memcpy + * BadSink : Copy string to data using memcpy + * Flow Variant: 44 Data/control flow: data passed as an argument from one function to a function in the same source file called via a function pointer + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +static void badSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_44_bad() +{ + wchar_t * data; + /* define a function pointer */ + void (*funcPtr) (wchar_t *) = badSink; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (wchar_t *)malloc(50*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + /* use the function pointer */ + funcPtr(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() uses the GoodSource with the BadSink */ +static void goodG2BSink(wchar_t * data) +{ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(wchar_t)); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + free(data); + } +} + +static void goodG2B() +{ + wchar_t * data; + void (*funcPtr) (wchar_t *) = goodG2BSink; + data = NULL; + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (wchar_t *)malloc(100*sizeof(wchar_t)); + if (data == NULL) {exit(-1);} + data[0] = L'\0'; /* null terminate */ + funcPtr(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_44_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_44_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_wchar_t_memcpy_44_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52a.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52a.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-52a.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: memmove + * BadSink : Copy string to data using memmove() + * Flow Variant: 52 Data flow: data passed as an argument from one function to another to another in three different source files + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L""AAAAAAAAAA"" + +#ifndef OMITBAD + +/* bad function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52b_badSink(wchar_t * data); + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = (wchar_t *)malloc(10*sizeof(wchar_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52b_badSink(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* good function declaration */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52b_goodG2BSink(wchar_t * data); + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + wchar_t * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = (wchar_t *)malloc((10+1)*sizeof(wchar_t)); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52b_goodG2BSink(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_wchar_t_memmove_52_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_06.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_06.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE193.label.xml +Template File: sources-sink-06.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate memory for a string, but do not allocate space for NULL terminator + * GoodSource: Allocate enough memory for a string and the NULL terminator + * Sink: cpy + * BadSink : Copy string to data using strcpy() + * Flow Variant: 06 Control flow: if(STATIC_CONST_FIVE==5) and if(STATIC_CONST_FIVE!=5) + * + * */ + +#include ""std_testcase.h"" + +#ifndef _WIN32 +#include +#endif + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING ""AAAAAAAAAA"" + +/* The variable below is declared ""const"", so a tool should be able + * to identify that reads of this will always give its initialized value. */ +static const int STATIC_CONST_FIVE = 5; + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_06_bad() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FLAW: Did not leave space for a null terminator */ + data = (char *)malloc(10*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B1() - use goodsource and badsink by changing the STATIC_CONST_FIVE==5 to STATIC_CONST_FIVE!=5 */ +static void goodG2B1() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE!=5) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine(""Benign, fixed string""); + } + else + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + data = NULL; + if(STATIC_CONST_FIVE==5) + { + /* FIX: Allocate space for a null terminator */ + data = (char *)malloc((10+1)*sizeof(char)); + if (data == NULL) {exit(-1);} + } + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ + strcpy(data, source); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_06_good() +{ + goodG2B1(); + goodG2B2(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_06_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE193_char_cpy_06_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_17.c,CWE122,bad,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_17.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.string.label.xml +Template File: sources-sink-17.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: ncat + * BadSink : Copy string to data using strncat + * Flow Variant: 17 Control flow: for loops + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_17_bad() +{ + int i; + char * data; + data = NULL; + for(i = 0; i < 1; i++) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ +static void goodG2B() +{ + int h; + char * data; + data = NULL; + for(h = 0; h < 1; h++) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (char *)malloc(100*sizeof(char)); + if (data == NULL) {exit(-1);} + data[0] = '\0'; /* null terminate */ + } + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_17_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_17_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_ncat_17_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_12.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_12.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-12.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate using malloc() and set data pointer to a small buffer + * GoodSource: Allocate using malloc() and set data pointer to a large buffer + * Sink: memcpy + * BadSink : Copy int64_t array to data using memcpy + * Flow Variant: 12 Control flow: if(globalReturnsTrueOrFalse()) + * + * */ + +#include ""std_testcase.h"" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_12_bad() +{ + int64_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (int64_t *)malloc(50*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B() - use goodsource and badsink by changing the ""if"" so that + * both branches use the GoodSource */ +static void goodG2B() +{ + int64_t * data; + data = NULL; + if(globalReturnsTrueOrFalse()) + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + else + { + /* FIX: Allocate and point data to a large buffer that is at least as large as the large buffer used in the sink */ + data = (int64_t *)malloc(100*sizeof(int64_t)); + if (data == NULL) {exit(-1);} + } + { + int64_t source[100] = {0}; /* fill with 0's */ + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + memcpy(data, source, 100*sizeof(int64_t)); + printLongLongLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_12_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine(""Calling good()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_12_good(); + printLine(""Finished good()""); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine(""Calling bad()...""); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_12_bad(); + printLine(""Finished bad()""); +#endif /* OMITBAD */ + return 0; +} + +#endif +" +CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_66b.c,CWE122,good,"/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_66b.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE806.label.xml +Template File: sources-sink-66b.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Initialize data as a large string + * GoodSource: Initialize data as a small string + * Sinks: ncpy + * BadSink : Copy data to string using strncpy + * Flow Variant: 66 Data flow: data passed in an array from one function to another in different source files + * + * */ + +#include ""std_testcase.h"" + +#include + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_66b_badSink(char * dataArray[]) +{ + /* copy data out of dataArray */ + char * data = dataArray[2]; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +/* goodG2B uses the GoodSource with the BadSink */ +void CWE122_Heap_Based_Buffer_Overflow__c_CWE806_char_ncpy_66b_goodG2BSink(char * dataArray[]) +{ + char * data = dataArray[2]; + { + char dest[50] = """"; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + strncpy(dest, data, strlen(data)); + dest[50-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +#endif /* OMITGOOD */ +"