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