@@ -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 |