| @@ -0,0 +1,134 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_02.c | |||
| Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml | |||
| Template File: sources-sink-02.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: 02 Control flow: if(1) and if(0) | |||
| * | |||
| * */ | |||
| #include "std_testcase.h" | |||
| #ifndef OMITBAD | |||
| void CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_02_bad() | |||
| { | |||
| int * data; | |||
| data = NULL; | |||
| if(1) | |||
| { | |||
| /* 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 | |||
| /* goodG2B1() - use goodsource and badsink by changing the 1 to 0 */ | |||
| static void goodG2B1() | |||
| { | |||
| int * data; | |||
| data = NULL; | |||
| if(0) | |||
| { | |||
| /* 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}; | |||
| 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); | |||
| } | |||
| } | |||
| /* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ | |||
| static void goodG2B2() | |||
| { | |||
| int * data; | |||
| data = NULL; | |||
| if(1) | |||
| { | |||
| /* 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_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__CWE131_loop_02_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_02_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,134 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_03.c | |||
| Label Definition File: CWE122_Heap_Based_Buffer_Overflow__CWE131.label.xml | |||
| Template File: sources-sink-03.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: 03 Control flow: if(5==5) and if(5!=5) | |||
| * | |||
| * */ | |||
| #include "std_testcase.h" | |||
| #ifndef OMITBAD | |||
| void CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_03_bad() | |||
| { | |||
| int * data; | |||
| data = NULL; | |||
| if(5==5) | |||
| { | |||
| /* 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 | |||
| /* 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 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); | |||
| } | |||
| } | |||
| /* 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 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_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__CWE131_loop_03_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE122_Heap_Based_Buffer_Overflow__CWE131_loop_03_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,274 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE124_Buffer_Underwrite__CWE839_connect_socket_01.c | |||
| Label Definition File: CWE124_Buffer_Underwrite__CWE839.label.xml | |||
| Template File: sources-sinks-01.tmpl.c | |||
| */ | |||
| /* | |||
| * @description | |||
| * CWE: 124 Buffer Underwrite | |||
| * BadSource: connect_socket Read data using a connect socket (client side) | |||
| * GoodSource: Non-negative but less than 10 | |||
| * Sinks: | |||
| * GoodSink: Ensure the array index is valid | |||
| * BadSink : Improperly check the array index by not checking the lower bound | |||
| * Flow Variant: 01 Baseline | |||
| * | |||
| * */ | |||
| #include "std_testcase.h" | |||
| #ifdef _WIN32 | |||
| #include <winsock2.h> | |||
| #include <windows.h> | |||
| #include <direct.h> | |||
| #pragma comment(lib, "ws2_32") /* include ws2_32.lib when linking */ | |||
| #define CLOSE_SOCKET closesocket | |||
| #else /* NOT _WIN32 */ | |||
| #include <sys/types.h> | |||
| #include <sys/socket.h> | |||
| #include <netinet/in.h> | |||
| #include <arpa/inet.h> | |||
| #include <unistd.h> | |||
| #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 CWE124_Buffer_Underwrite__CWE839_connect_socket_01_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 i; | |||
| int buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This code does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| 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 i; | |||
| int buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This code does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| 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; | |||
| { | |||
| #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 i; | |||
| int buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer underwrite */ | |||
| 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 CWE124_Buffer_Underwrite__CWE839_connect_socket_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()..."); | |||
| CWE124_Buffer_Underwrite__CWE839_connect_socket_01_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE124_Buffer_Underwrite__CWE839_connect_socket_01_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,428 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE124_Buffer_Underwrite__CWE839_connect_socket_02.c | |||
| Label Definition File: CWE124_Buffer_Underwrite__CWE839.label.xml | |||
| Template File: sources-sinks-02.tmpl.c | |||
| */ | |||
| /* | |||
| * @description | |||
| * CWE: 124 Buffer Underwrite | |||
| * BadSource: connect_socket Read data using a connect socket (client side) | |||
| * GoodSource: Non-negative but less than 10 | |||
| * Sinks: | |||
| * GoodSink: Ensure the array index is valid | |||
| * BadSink : Improperly check the array index by not checking the lower bound | |||
| * Flow Variant: 02 Control flow: if(1) and if(0) | |||
| * | |||
| * */ | |||
| #include "std_testcase.h" | |||
| #ifdef _WIN32 | |||
| #include <winsock2.h> | |||
| #include <windows.h> | |||
| #include <direct.h> | |||
| #pragma comment(lib, "ws2_32") /* include ws2_32.lib when linking */ | |||
| #define CLOSE_SOCKET closesocket | |||
| #else /* NOT _WIN32 */ | |||
| #include <sys/types.h> | |||
| #include <sys/socket.h> | |||
| #include <netinet/in.h> | |||
| #include <arpa/inet.h> | |||
| #include <unistd.h> | |||
| #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 CWE124_Buffer_Underwrite__CWE839_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[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This code does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| 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 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[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer underwrite */ | |||
| 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(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[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer underwrite */ | |||
| 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 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[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This code does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| 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(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[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This code does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| buffer[data] = 1; | |||
| /* Print the array values */ | |||
| for(i = 0; i < 10; i++) | |||
| { | |||
| printIntLine(buffer[i]); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is negative."); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void CWE124_Buffer_Underwrite__CWE839_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()..."); | |||
| CWE124_Buffer_Underwrite__CWE839_connect_socket_02_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE124_Buffer_Underwrite__CWE839_connect_socket_02_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,256 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE126_Buffer_Overread__CWE129_connect_socket_01.c | |||
| Label Definition File: CWE126_Buffer_Overread__CWE129.label.xml | |||
| Template File: sources-sinks-01.tmpl.c | |||
| */ | |||
| /* | |||
| * @description | |||
| * CWE: 126 Buffer Overread | |||
| * 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: 01 Baseline | |||
| * | |||
| * */ | |||
| #include "std_testcase.h" | |||
| #ifdef _WIN32 | |||
| #include <winsock2.h> | |||
| #include <windows.h> | |||
| #include <direct.h> | |||
| #pragma comment(lib, "ws2_32") /* include ws2_32.lib when linking */ | |||
| #define CLOSE_SOCKET closesocket | |||
| #else /* NOT _WIN32 */ | |||
| #include <sys/types.h> | |||
| #include <sys/socket.h> | |||
| #include <netinet/in.h> | |||
| #include <arpa/inet.h> | |||
| #include <unistd.h> | |||
| #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 CWE126_Buffer_Overread__CWE129_connect_socket_01_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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access an index of the array that is above the upper bound | |||
| * This check does not check the upper bounds of the array index */ | |||
| if (data >= 0) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| 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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access an index of the array that is above the upper bound | |||
| * This check does not check the upper bounds of the array index */ | |||
| if (data >= 0) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is negative"); | |||
| } | |||
| } | |||
| } | |||
| /* 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 buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer overread */ | |||
| if (data >= 0 && data < (10)) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is out-of-bounds"); | |||
| } | |||
| } | |||
| } | |||
| void CWE126_Buffer_Overread__CWE129_connect_socket_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()..."); | |||
| CWE126_Buffer_Overread__CWE129_connect_socket_01_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE126_Buffer_Overread__CWE129_connect_socket_01_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,398 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE126_Buffer_Overread__CWE129_connect_socket_02.c | |||
| Label Definition File: CWE126_Buffer_Overread__CWE129.label.xml | |||
| Template File: sources-sinks-02.tmpl.c | |||
| */ | |||
| /* | |||
| * @description | |||
| * CWE: 126 Buffer Overread | |||
| * 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 <winsock2.h> | |||
| #include <windows.h> | |||
| #include <direct.h> | |||
| #pragma comment(lib, "ws2_32") /* include ws2_32.lib when linking */ | |||
| #define CLOSE_SOCKET closesocket | |||
| #else /* NOT _WIN32 */ | |||
| #include <sys/types.h> | |||
| #include <sys/socket.h> | |||
| #include <netinet/in.h> | |||
| #include <arpa/inet.h> | |||
| #include <unistd.h> | |||
| #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 CWE126_Buffer_Overread__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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access an index of the array that is above the upper bound | |||
| * This check does not check the upper bounds of the array index */ | |||
| if (data >= 0) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is negative"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| #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 buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer overread */ | |||
| if (data >= 0 && data < (10)) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| 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(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 buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer overread */ | |||
| if (data >= 0 && data < (10)) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is out-of-bounds"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /* 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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access an index of the array that is above the upper bound | |||
| * This check does not check the upper bounds of the array index */ | |||
| if (data >= 0) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| 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(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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access an index of the array that is above the upper bound | |||
| * This check does not check the upper bounds of the array index */ | |||
| if (data >= 0) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is negative"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void CWE126_Buffer_Overread__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()..."); | |||
| CWE126_Buffer_Overread__CWE129_connect_socket_02_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE126_Buffer_Overread__CWE129_connect_socket_02_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,398 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE126_Buffer_Overread__CWE129_connect_socket_03.c | |||
| Label Definition File: CWE126_Buffer_Overread__CWE129.label.xml | |||
| Template File: sources-sinks-03.tmpl.c | |||
| */ | |||
| /* | |||
| * @description | |||
| * CWE: 126 Buffer Overread | |||
| * 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 <winsock2.h> | |||
| #include <windows.h> | |||
| #include <direct.h> | |||
| #pragma comment(lib, "ws2_32") /* include ws2_32.lib when linking */ | |||
| #define CLOSE_SOCKET closesocket | |||
| #else /* NOT _WIN32 */ | |||
| #include <sys/types.h> | |||
| #include <sys/socket.h> | |||
| #include <netinet/in.h> | |||
| #include <arpa/inet.h> | |||
| #include <unistd.h> | |||
| #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 CWE126_Buffer_Overread__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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access an index of the array that is above the upper bound | |||
| * This check does not check the upper bounds of the array index */ | |||
| if (data >= 0) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| 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) | |||
| { | |||
| { | |||
| #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 buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer overread */ | |||
| if (data >= 0 && data < (10)) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| 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) | |||
| { | |||
| { | |||
| #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 buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer overread */ | |||
| if (data >= 0 && data < (10)) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| 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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access an index of the array that is above the upper bound | |||
| * This check does not check the upper bounds of the array index */ | |||
| if (data >= 0) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| 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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access an index of the array that is above the upper bound | |||
| * This check does not check the upper bounds of the array index */ | |||
| if (data >= 0) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is negative"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void CWE126_Buffer_Overread__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()..."); | |||
| CWE126_Buffer_Overread__CWE129_connect_socket_03_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE126_Buffer_Overread__CWE129_connect_socket_03_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,256 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE127_Buffer_Underread__CWE839_connect_socket_01.c | |||
| Label Definition File: CWE127_Buffer_Underread__CWE839.label.xml | |||
| Template File: sources-sinks-01.tmpl.c | |||
| */ | |||
| /* | |||
| * @description | |||
| * CWE: 127 Buffer Underread | |||
| * BadSource: connect_socket Read data using a connect socket (client side) | |||
| * GoodSource: Non-negative but less than 10 | |||
| * Sinks: | |||
| * GoodSink: Ensure the array index is valid | |||
| * BadSink : Improperly check the array index by not checking to see if the value is negative | |||
| * Flow Variant: 01 Baseline | |||
| * | |||
| * */ | |||
| #include "std_testcase.h" | |||
| #ifdef _WIN32 | |||
| #include <winsock2.h> | |||
| #include <windows.h> | |||
| #include <direct.h> | |||
| #pragma comment(lib, "ws2_32") /* include ws2_32.lib when linking */ | |||
| #define CLOSE_SOCKET closesocket | |||
| #else /* NOT _WIN32 */ | |||
| #include <sys/types.h> | |||
| #include <sys/socket.h> | |||
| #include <netinet/in.h> | |||
| #include <arpa/inet.h> | |||
| #include <unistd.h> | |||
| #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 CWE127_Buffer_Underread__CWE839_connect_socket_01_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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This check does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is too big."); | |||
| } | |||
| } | |||
| } | |||
| #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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This check does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is too big."); | |||
| } | |||
| } | |||
| } | |||
| /* 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 buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer underread */ | |||
| if (data >= 0 && data < (10)) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is out-of-bounds"); | |||
| } | |||
| } | |||
| } | |||
| void CWE127_Buffer_Underread__CWE839_connect_socket_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()..."); | |||
| CWE127_Buffer_Underread__CWE839_connect_socket_01_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE127_Buffer_Underread__CWE839_connect_socket_01_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,398 @@ | |||
| /* TEMPLATE GENERATED TESTCASE FILE | |||
| Filename: CWE127_Buffer_Underread__CWE839_connect_socket_02.c | |||
| Label Definition File: CWE127_Buffer_Underread__CWE839.label.xml | |||
| Template File: sources-sinks-02.tmpl.c | |||
| */ | |||
| /* | |||
| * @description | |||
| * CWE: 127 Buffer Underread | |||
| * BadSource: connect_socket Read data using a connect socket (client side) | |||
| * GoodSource: Non-negative but less than 10 | |||
| * Sinks: | |||
| * GoodSink: Ensure the array index is valid | |||
| * BadSink : Improperly check the array index by not checking to see if the value is negative | |||
| * Flow Variant: 02 Control flow: if(1) and if(0) | |||
| * | |||
| * */ | |||
| #include "std_testcase.h" | |||
| #ifdef _WIN32 | |||
| #include <winsock2.h> | |||
| #include <windows.h> | |||
| #include <direct.h> | |||
| #pragma comment(lib, "ws2_32") /* include ws2_32.lib when linking */ | |||
| #define CLOSE_SOCKET closesocket | |||
| #else /* NOT _WIN32 */ | |||
| #include <sys/types.h> | |||
| #include <sys/socket.h> | |||
| #include <netinet/in.h> | |||
| #include <arpa/inet.h> | |||
| #include <unistd.h> | |||
| #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 CWE127_Buffer_Underread__CWE839_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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This check does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is too big."); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| #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 buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer underread */ | |||
| if (data >= 0 && data < (10)) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| 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(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 buffer[10] = { 0 }; | |||
| /* FIX: Properly validate the array index and prevent a buffer underread */ | |||
| if (data >= 0 && data < (10)) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is out-of-bounds"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /* 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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This check does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is too big."); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /* 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 buffer[10] = { 0 }; | |||
| /* POTENTIAL FLAW: Attempt to access a negative index of the array | |||
| * This check does not check to see if the array index is negative */ | |||
| if (data < 10) | |||
| { | |||
| printIntLine(buffer[data]); | |||
| } | |||
| else | |||
| { | |||
| printLine("ERROR: Array index is too big."); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void CWE127_Buffer_Underread__CWE839_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()..."); | |||
| CWE127_Buffer_Underread__CWE839_connect_socket_02_good(); | |||
| printLine("Finished good()"); | |||
| #endif /* OMITGOOD */ | |||
| #ifndef OMITBAD | |||
| printLine("Calling bad()..."); | |||
| CWE127_Buffer_Underread__CWE839_connect_socket_02_bad(); | |||
| printLine("Finished bad()"); | |||
| #endif /* OMITBAD */ | |||
| return 0; | |||
| } | |||
| #endif | |||