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
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*
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-
97169void 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}
0 commit comments