Skip to content

Commit 9fde105

Browse files
Merge pull request FreeRTOS#4 from FreeRTOS/labs/ipv6_multi
Labs/ipv6 multi merge to fork
2 parents 83d1d8b + af68d78 commit 9fde105

File tree

10 files changed

+167
-36
lines changed

10 files changed

+167
-36
lines changed

FreeRTOS_DHCP.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,8 @@
217217
/*
218218
* Interpret message received on the DHCP socket.
219219
*/
220-
_static BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType,
221-
NetworkEndPoint_t * pxEndPoint );
220+
static BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType,
221+
NetworkEndPoint_t * pxEndPoint );
222222

223223
/*
224224
* Generate a DHCP request packet, and send it on the DHCP socket.
@@ -966,8 +966,8 @@
966966
*
967967
* @return pdPASS: if DHCP options are received correctly; pdFAIL: Otherwise.
968968
*/
969-
_static BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType,
970-
NetworkEndPoint_t * pxEndPoint )
969+
static BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType,
970+
NetworkEndPoint_t * pxEndPoint )
971971
{
972972
uint8_t * pucUDPPayload;
973973
int32_t lBytes;

FreeRTOS_DNS.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,8 @@
377377
}
378378
#include "pack_struct_end.h"
379379
typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
380-
/** @brief this is for debugging only. */
381-
static struct freertos_addrinfo * pxLastInfo = NULL;
380+
/** @brief Used for additional error checking when asserts are enabled. */
381+
_static struct freertos_addrinfo * pxLastInfo = NULL;
382382

383383

384384
/**

test/cbmc/proofs/DHCP/DHCPProcessEndPoint/DHCPProcessEndPoint_harness.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ Socket_t FreeRTOS_socket( BaseType_t xDomain,
9797
* Function Abstraction:
9898
* prvProcessDHCPReplies has been proved memory safe in ProcessDHCPReplies.
9999
****************************************************************/
100-
BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType,
101-
NetworkEndPoint_t * pxEndPoint )
100+
BaseType_t __CPROVER_file_local_FreeRTOS_DHCP_c_prvProcessDHCPReplies( BaseType_t xExpectedMessageType,
101+
NetworkEndPoint_t * pxEndPoint )
102102
{
103103
return nondet_BaseType();
104104
}

test/cbmc/proofs/DNS/DNSHandlePacket/DNShandlePacket_harness.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@
1010

1111
/* Function Abstraction:
1212
* Function prvParseDNSReply is proven to be correct separately.
13-
* The proof can be found here: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/tree/labs/ipv6_multi/test/cbmc/proofs/ParseDNSReply */
14-
uint32_t prvParseDNSReply( uint8_t * pucUDPPayloadBuffer,
15-
size_t uxBufferLength,
16-
struct freertos_addrinfo ** ppxAddressInfo,
17-
BaseType_t xExpected )
13+
* The proof can be found here: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/tree/labs/ipv6_multi/test/cbmc/proofs/ParseDNSReply.
14+
* Note: this function is defined as static in FreeRTOS_DNS.c.
15+
* To access this function outside of that file, we have used
16+
* a CBMC flag (--export-file-local-symbols). Using that flag
17+
* mangles the names of static functions. Thus, the below
18+
* function name is also mangled. */
19+
uint32_t __CPROVER_file_local_FreeRTOS_DNS_c_prvParseDNSReply( uint8_t * pucUDPPayloadBuffer,
20+
size_t uxBufferLength,
21+
struct freertos_addrinfo ** ppxAddressInfo,
22+
BaseType_t xExpected )
1823
{
1924
uint32_t ulReturn;
2025

@@ -37,9 +42,13 @@ typedef struct xDNSMessage DNSMessage_t;
3742
void harness()
3843
{
3944
NetworkBufferDescriptor_t xNetworkBuffer;
45+
size_t xEthernetBufferSize;
4046

41-
xNetworkBuffer.pucEthernetBuffer = malloc( sizeof( UDPPacket_t ) + sizeof( DNSMessage_t ) );
47+
/* Allocate arbitrary number of bytes. */
48+
xNetworkBuffer.pucEthernetBuffer = malloc( xEthernetBufferSize );
49+
xNetworkBuffer.xDataLength = xEthernetBufferSize;
4250

43-
/* The parameter to the function cannot be NULL. */
51+
/* The parameter to the function cannot be NULL. This function is called
52+
* by the +TCP stack internally and is not an API. */
4453
ulDNSHandlePacket( &xNetworkBuffer );
4554
}

test/cbmc/proofs/DNS/DNSHandlePacket/Makefile.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"ENTRY": "DNShandlePacket",
3-
"CBMCFLAGS": "--unwind 1",
3+
"CBMCFLAGS":"" ,
44
"OBJS":
55
[
66
"$(ENTRY)_harness.goto",
@@ -10,5 +10,10 @@
1010
[
1111
"ipconfigUSE_DNS=1",
1212
"ipconfigDNS_USE_CALLBACKS=1"
13+
],
14+
"OPT":
15+
[
16+
# Flag to access the static function of a file
17+
"--export-file-local-symbols"
1318
]
1419
}

test/cbmc/proofs/DNS/DNSgetHostByName_a/DNSgetHostByName_a_harness.c

Lines changed: 103 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "FreeRTOS_UDP_IP.h"
1515
#include "FreeRTOS_DNS.h"
1616
#include "FreeRTOS_DHCP.h"
17+
#include "FreeRTOS_Routing.h"
1718
#include "NetworkBufferManagement.h"
1819
#include "NetworkInterface.h"
1920

@@ -37,6 +38,68 @@
3738
* bound the iterations of strcmp.
3839
****************************************************************/
3940

41+
/* This variable is defined in FreeRTOS_DNS.c */
42+
extern struct freertos_addrinfo * pxLastInfo;
43+
44+
/* Function Abstraction:
45+
* pxGetNetworkBufferWithDescriptor allocates a Network buffer after taking it
46+
* out of a list of network buffers maintained by the TCP stack. To prove the memory
47+
* safety of the function under test, we do not need to initialise the list - it
48+
* would make the proof more complex and deviate from its objective.
49+
* Keeping this in mind, the below stub perform some basic checks required and
50+
* allocates the required amount of memory without making any other assumptions
51+
* whatsoever.
52+
*/
53+
NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes,
54+
TickType_t xBlockTimeTicks )
55+
{
56+
__CPROVER_assert(
57+
xRequestedSizeBytes + ipBUFFER_PADDING < CBMC_MAX_OBJECT_SIZE,
58+
"pxGetNetworkBufferWithDescriptor: request too big" );
59+
60+
/* Arbitrarily return NULL or a valid pointer. */
61+
NetworkBufferDescriptor_t * pxReturn = nondet_bool() ? NULL : malloc( sizeof( *pxReturn ) );
62+
63+
if( pxReturn != NULL )
64+
{
65+
/* Allocate the ethernet buffer. */
66+
pxReturn->pucEthernetBuffer = malloc( xRequestedSizeBytes + ipBUFFER_PADDING );
67+
68+
__CPROVER_assume( pxReturn->pucEthernetBuffer != NULL );
69+
70+
pxReturn->xDataLength = xRequestedSizeBytes;
71+
72+
/* Move the pointer ipBUFFER_PADDING (defined in FreeRTOS_IP.h) bytes
73+
* ahead. This space is used to store data by the TCP stack for its own
74+
* use whilst processing the packet. */
75+
pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
76+
}
77+
78+
return pxReturn;
79+
}
80+
81+
/* Function Abstraction:
82+
* vReleaseNetworkBufferAndDescriptor frees the memory associated with the ethernet
83+
* buffer and returns the network buffer to a list maintained by the +TCP stack. But
84+
* for the function under test, we do not need to initialise and maintain the list,
85+
* as it would make the proof unnecessarily complex.
86+
* Keeping this in mind, the stub below asserts some basic condition(s) and frees
87+
* the memory allocated by the pxGetNetworkBufferWithDescriptor stub above.
88+
*/
89+
void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
90+
{
91+
__CPROVER_assert( pxNetworkBuffer != NULL,
92+
"Precondition: pxNetworkBuffer != NULL" );
93+
94+
if( pxNetworkBuffer->pucEthernetBuffer != NULL )
95+
{
96+
pxNetworkBuffer->pucEthernetBuffer -= ipBUFFER_PADDING;
97+
free( pxNetworkBuffer->pucEthernetBuffer );
98+
}
99+
100+
free( pxNetworkBuffer );
101+
}
102+
40103
/****************************************************************
41104
* Abstract prvParseDNSReply proved memory safe in ParseDNSReply.
42105
*
@@ -47,9 +110,10 @@
47110
* function.
48111
****************************************************************/
49112

50-
uint32_t prvParseDNSReply( uint8_t * pucUDPPayloadBuffer,
51-
size_t xBufferLength,
52-
BaseType_t xExpected )
113+
uint32_t __CPROVER_file_local_FreeRTOS_DNS_c_prvParseDNSReply( uint8_t * pucUDPPayloadBuffer,
114+
size_t xBufferLength,
115+
struct freertos_addrinfo ** ppxAddressInfo,
116+
BaseType_t xExpected )
53117
{
54118
__CPROVER_assert( pucUDPPayloadBuffer != NULL,
55119
"Precondition: pucUDPPayloadBuffer != NULL" );
@@ -67,9 +131,10 @@ uint32_t prvParseDNSReply( uint8_t * pucUDPPayloadBuffer,
67131
* unconstrained data and returns and unconstrained length.
68132
****************************************************************/
69133

70-
size_t prvCreateDNSMessage( uint8_t * pucUDPPayloadBuffer,
71-
const char * pcHostName,
72-
TickType_t uxIdentifier )
134+
size_t __CPROVER_file_local_FreeRTOS_DNS_c_prvCreateDNSMessage( uint8_t * pucUDPPayloadBuffer,
135+
const char * pcHostName,
136+
TickType_t uxIdentifier,
137+
UBaseType_t uxHostType )
73138
{
74139
__CPROVER_assert( pucUDPPayloadBuffer != NULL,
75140
"Precondition: pucUDPPayloadBuffer != NULL" );
@@ -90,24 +155,49 @@ void func( const char * pcHostName,
90155
{
91156
}
92157

158+
159+
/** A list of all network end-points. Each element has a next pointer. */
160+
extern struct xNetworkEndPoint * pxNetworkEndPoints;
161+
162+
/** A list of all network interfaces: */
163+
extern struct xNetworkInterface * pxNetworkInterfaces;
164+
165+
93166
/****************************************************************
94167
* The proof for FreeRTOS_gethostbyname_a.
95168
****************************************************************/
96-
97169
void harness()
98170
{
99171
size_t len;
100172

101-
__CPROVER_assume( len <= MAX_HOSTNAME_LEN );
102-
char * pcHostName = safeMalloc( len );
173+
__CPROVER_assume( ( len <= MAX_HOSTNAME_LEN ) && ( len > 0 ) );
103174

104-
__CPROVER_assume( len > 0 ); /* prvProcessDNSCache strcmp */
105-
__CPROVER_assume( pcHostName != NULL );
106-
pcHostName[ len - 1 ] = NULL;
175+
/* Arbitrarily assign a proper memory or NULL to the hostname. */
176+
char * pcHostName = nondet_bool() ? malloc( len ) : NULL;
107177

108-
FOnDNSEvent pCallback = func;
178+
/* NULL terminate the string if the pcHostName is allocated. */
179+
if( pcHostName != NULL )
180+
{
181+
pcHostName[ len - 1 ] = NULL;
182+
}
183+
184+
/* Arbitrarily assign a NULL/valid-function to the function-pointer
185+
* being used in the callback. */
186+
FOnDNSEvent pCallback = nondet_bool() ? func : NULL;
109187
TickType_t xTimeout;
110188
void * pvSearchID;
111189

190+
/* Assume that the list of interfaces/endpoints is not initialized.
191+
* Note: These variables are defined in FreeRTOS_Routing.c in global scope.
192+
* They serve as a list to the network interfaces and the corresponding
193+
* endpoints respectively. And are defined as NULL initially. */
194+
__CPROVER_assume( pxNetworkInterfaces == NULL );
195+
__CPROVER_assume( pxNetworkEndPoints == NULL );
196+
197+
/* Assume that the last info pointer is NULL at the beginning. This is defined
198+
* in FreeRTOS_DNS.c and is used for debugging purpose. It is declared NULL
199+
* initially. */
200+
__CPROVER_assume( pxLastInfo == NULL );
201+
112202
FreeRTOS_gethostbyname_a( pcHostName, pCallback, pvSearchID, xTimeout );
113203
}

test/cbmc/proofs/DNS/DNSgetHostByName_a/Makefile.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,36 @@
66
"callback": 1,
77
"MAX_HOSTNAME_LEN": 10,
88
"HOSTNAME_UNWIND": "__eval {MAX_HOSTNAME_LEN} + 1",
9+
"DNS_REQ_ATTEMPTS":2,
10+
"DNS_REQUEST_ATTEMPTS": "__eval {DNS_REQ_ATTEMPTS} + 1",
11+
"DNS_CACHE_ENTRIES":3,
12+
"DNS_CACHE_ENTRIES_UNWIND": "__eval {DNS_CACHE_ENTRIES} + 1",
913
"CBMCFLAGS":
1014
[
1115
"--unwind 1",
12-
"--unwindset prvCreateDNSMessage.0:{HOSTNAME_UNWIND},prvCreateDNSMessage.1:{HOSTNAME_UNWIND},prvGetHostByName.0:{HOSTNAME_UNWIND},prvProcessDNSCache.0:5,strlen.0:{HOSTNAME_UNWIND},__builtin___strcpy_chk.0:{HOSTNAME_UNWIND},strcmp.0:{HOSTNAME_UNWIND},xTaskResumeAll.0:{HOSTNAME_UNWIND},xTaskResumeAll.1:{HOSTNAME_UNWIND},strcpy.0:{HOSTNAME_UNWIND}",
16+
"--unwindset FreeRTOS_freeaddrinfo.0:2,__CPROVER_file_local_FreeRTOS_DNS_c_prvReadDNSCache.0:2,__CPROVER_file_local_FreeRTOS_DNS_c_prvGetHostByName.1:{DNS_REQUEST_ATTEMPTS},__CPROVER_file_local_FreeRTOS_DNS_c_prvProcessDNSCache.0:{DNS_CACHE_ENTRIES_UNWIND},prvCreateDNSMessage.0:{HOSTNAME_UNWIND},prvCreateDNSMessage.1:{HOSTNAME_UNWIND},__CPROVER_file_local_FreeRTOS_DNS_c_prvGetHostByName.0:{HOSTNAME_UNWIND},prvProcessDNSCache.0:5,strlen.0:{HOSTNAME_UNWIND},__builtin___strcpy_chk.0:{HOSTNAME_UNWIND},strcmp.0:{HOSTNAME_UNWIND},xTaskResumeAll.0:{HOSTNAME_UNWIND},xTaskResumeAll.1:{HOSTNAME_UNWIND},strcpy.0:{HOSTNAME_UNWIND},strncpy.0:255",
1317
"--nondet-static"
1418
],
1519
"OBJS":
1620
[
1721
"$(ENTRY)_harness.goto",
1822
"$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto",
1923
"$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto",
24+
"$(FREERTOS_PLUS_TCP)/FreeRTOS_Routing.goto",
2025
"$(FREERTOS_PLUS_TCP)/FreeRTOS_DNS.goto",
2126
"$(FREERTOS_PLUS_TCP)/FreeRTOS_IP.goto"
2227
],
2328
"DEF":
2429
[
2530
"ipconfigDNS_USE_CALLBACKS={callback}",
2631
"MAX_HOSTNAME_LEN={MAX_HOSTNAME_LEN}",
32+
"ipconfigDNS_REQUEST_ATTEMPTS={DNS_REQ_ATTEMPTS}",
2733
# This value is defined only when ipconfigUSE_DNS_CACHE==1
2834
"ipconfigDNS_CACHE_NAME_LENGTH=254"
35+
],
36+
"OPT":
37+
[
38+
# Flag to access the static function of a file
39+
"--export-file-local-symbols"
2940
]
3041
}

test/cbmc/proofs/DNS/DNSlookup/DNSlookup_harness.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
/* FreeRTOS+TCP includes. */
77
#include "FreeRTOS_IP.h"
8+
#include "FreeRTOS_Sockets.h"
89
#include "FreeRTOS_DNS.h"
910
#include "FreeRTOS_IP_Private.h"
1011

test/cbmc/proofs/ProcessDHCPReplies/Makefile.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"CBMCFLAGS": [
2727
# "--nondet-static",
2828
"--unwind 1",
29-
"--unwindset memcmp.0:7,prvProcessDHCPReplies.0:{BUFFER_PAYLOAD}"
29+
"--unwindset memcmp.0:7,__CPROVER_file_local_FreeRTOS_DHCP_c_prvProcessDHCPReplies.0:{BUFFER_PAYLOAD}"
3030
],
3131

3232
"OBJS":
@@ -44,5 +44,11 @@
4444
[
4545
"CBMC_DHCPMESSAGE_HEADER_SIZE={BUFFER_HEADER}",
4646
"CBMC_FREERTOS_RECVFROM_BUFFER_BOUND={BUFFER_SIZE}"
47+
],
48+
49+
"OPT":
50+
[
51+
# Flag to access the static function of a file
52+
"--export-file-local-symbols"
4753
]
4854
}

test/cbmc/proofs/ProcessDHCPReplies/ProcessDHCPReplies_harness.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,34 @@
1313
#include "FreeRTOS_UDP_IP.h"
1414
#include "FreeRTOS_DHCP.h"
1515
#include "FreeRTOS_ARP.h"
16-
16+
#include "FreeRTOS_Routing.h"
1717

1818
/****************************************************************
1919
* Signature of function under test
20+
* The function name (prvProcessDHCPReplies) is mangled due to the
21+
* use of a CBMC flag (--export-file-local-symbols) which allows us
22+
* to access this static function outside the source file in which
23+
* it is defined.
2024
****************************************************************/
21-
22-
BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType );
25+
BaseType_t __CPROVER_file_local_FreeRTOS_DHCP_c_prvProcessDHCPReplies( BaseType_t xExpectedMessageType,
26+
NetworkEndPoint_t * pxEndPoint );
2327

2428
/****************************************************************
2529
* The proof for FreeRTOS_gethostbyname.
2630
****************************************************************/
27-
2831
void harness()
2932
{
3033
/* Omitting model of an unconstrained xDHCPData because xDHCPData is */
3134
/* the source of uninitialized data only on line 647 to set a */
3235
/* transaction id is an outgoing message */
3336

3437
BaseType_t xExpectedMessageType;
38+
NetworkEndPoint_t xEndPoint;
39+
40+
/* The function under test is a private (static) function called only by
41+
* the TCP stack. The stack asserts that the endpoint cannot be NULL
42+
* before the function under test is invoked. */
43+
NetworkEndPoint_t * pxEndPoint = &xEndPoint;
3544

36-
prvProcessDHCPReplies( xExpectedMessageType );
45+
__CPROVER_file_local_FreeRTOS_DHCP_c_prvProcessDHCPReplies( xExpectedMessageType, pxEndPoint );
3746
}

0 commit comments

Comments
 (0)