@@ -51,20 +51,24 @@ extern DHCPData_t xDHCPData;
51
51
extern Socket_t xDHCPv4Socket ;
52
52
void prvCreateDHCPSocket ( NetworkEndPoint_t * pxEndPoint );
53
53
54
- /* Static member defined in freertos_api.c */
55
- #ifdef CBMC_GETNETWORKBUFFER_FAILURE_BOUND
56
- extern uint32_t GetNetworkBuffer_failure_count ;
57
- #endif
54
+ uint32_t uxSocketCloseCnt = 0 ;
58
55
56
+ DHCPMessage_IPv4_t xDHCPMessage ;
59
57
60
58
59
+ void __CPROVER_file_local_FreeRTOS_DHCP_c_prvCloseDHCPSocket ( const NetworkEndPoint_t * pxEndPoint );
60
+
61
61
/****************************************************************
62
- * The signature of the function under test.
62
+ * vDHCPProcessEndPoint() is proved separately
63
63
****************************************************************/
64
64
65
65
void __CPROVER_file_local_FreeRTOS_DHCP_c_vDHCPProcessEndPoint ( BaseType_t xReset ,
66
66
BaseType_t xDoCheck ,
67
- NetworkEndPoint_t * pxEndPoint );
67
+ NetworkEndPoint_t * pxEndPoint )
68
+ {
69
+ __CPROVER_assert ( pxEndPoint != NULL ,
70
+ "FreeRTOS precondition: pxEndPoint != NULL" );
71
+ }
68
72
69
73
/****************************************************************
70
74
* Abstract prvProcessDHCPReplies proved memory safe in ProcessDHCPReplies.
@@ -111,25 +115,55 @@ BaseType_t vSocketBind( FreeRTOS_Socket_t * pxSocket,
111
115
NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor ( size_t xRequestedSizeBytes ,
112
116
TickType_t xBlockTimeTicks )
113
117
{
114
- NetworkBufferDescriptor_t * pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) malloc ( sizeof ( NetworkBufferDescriptor_t ) );
118
+ NetworkBufferDescriptor_t * pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) safeMalloc ( sizeof ( NetworkBufferDescriptor_t ) );
115
119
116
120
__CPROVER_assume ( pxNetworkBuffer != NULL );
117
121
__CPROVER_assume ( xRequestedSizeBytes > ( dhcpFIRST_OPTION_BYTE_OFFSET + sizeof ( MACAddress_t ) + ipIP_TYPE_OFFSET ) );
118
122
119
- pxNetworkBuffer -> pucEthernetBuffer = ( ( uint8_t * ) malloc ( xRequestedSizeBytes + ( ipIP_TYPE_OFFSET ) ) ) + ipIP_TYPE_OFFSET ;
123
+ pxNetworkBuffer -> pucEthernetBuffer = ( ( uint8_t * ) safeMalloc ( xRequestedSizeBytes + ( ipIP_TYPE_OFFSET ) ) );
120
124
__CPROVER_assume ( pxNetworkBuffer -> pucEthernetBuffer != NULL );
121
125
126
+ /* Increment with expected buffer padding */
127
+ pxNetworkBuffer -> pucEthernetBuffer += ipIP_TYPE_OFFSET ;
128
+
122
129
pxNetworkBuffer -> xDataLength = xRequestedSizeBytes ;
123
130
return pxNetworkBuffer ;
124
131
}
125
132
133
+ /* FreeRTOS_ReleaseUDPPayloadBuffer is mocked here and the memory
134
+ * is not freed as the buffer allocated by the FreeRTOS_recvfrom is static
135
+ * memory */
126
136
void FreeRTOS_ReleaseUDPPayloadBuffer ( void * pvBuffer )
127
137
{
128
138
__CPROVER_assert ( pvBuffer != NULL ,
129
139
"FreeRTOS precondition: pvBuffer != NULL" );
140
+ }
130
141
131
- /* Free buffer after adjusting offsets. */
132
- free ( ( ( ( uint8_t * ) pvBuffer ) - ( ipUDP_PAYLOAD_OFFSET_IPv4 + ipIP_TYPE_OFFSET ) ) );
142
+ /* For the DHCP process loop to be fully covered, we expect FreeRTOS_recvfrom
143
+ * to fail after few iterations. This is because vDHCPProcessEndPoint is proved
144
+ * separately and is stubbed out for this proof, which ideally is supposed to close
145
+ * the socket and end the loop. */
146
+ int32_t FreeRTOS_recvfrom ( Socket_t xSocket ,
147
+ void * pvBuffer ,
148
+ size_t uxBufferLength ,
149
+ BaseType_t xFlags ,
150
+ struct freertos_sockaddr * pxSourceAddress ,
151
+ socklen_t * pxSourceAddressLength )
152
+
153
+ {
154
+ static uint32_t recvRespCnt = 0 ;
155
+ int32_t retVal = -1 ;
156
+
157
+ __CPROVER_assert ( pvBuffer != NULL ,
158
+ "FreeRTOS precondition: pvBuffer != NULL" );
159
+
160
+ if ( ++ recvRespCnt < ( FR_RECV_FROM_SUCCESS_COUNT - 1 ) )
161
+ {
162
+ * ( ( void * * ) pvBuffer ) = ( void * ) & xDHCPMessage ;
163
+ retVal = sizeof ( xDHCPMessage );
164
+ }
165
+
166
+ return retVal ;
133
167
}
134
168
135
169
/****************************************************************
@@ -139,18 +173,18 @@ void FreeRTOS_ReleaseUDPPayloadBuffer( void * pvBuffer )
139
173
void harness ()
140
174
{
141
175
BaseType_t xReset ;
142
- BaseType_t xDoCheck ;
176
+ eDHCPState_t eExpectedState ;
143
177
144
- pxNetworkEndPoints = ( NetworkEndPoint_t * ) malloc ( sizeof ( NetworkEndPoint_t ) );
178
+ pxNetworkEndPoints = ( NetworkEndPoint_t * ) safeMalloc ( sizeof ( NetworkEndPoint_t ) );
145
179
__CPROVER_assume ( pxNetworkEndPoints != NULL );
146
180
147
181
/* Interface init. */
148
- pxNetworkEndPoints -> pxNetworkInterface = ( NetworkInterface_t * ) malloc ( sizeof ( NetworkInterface_t ) );
182
+ pxNetworkEndPoints -> pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc ( sizeof ( NetworkInterface_t ) );
149
183
__CPROVER_assume ( pxNetworkEndPoints -> pxNetworkInterface != NULL );
150
184
151
185
if ( nondet_bool () )
152
186
{
153
- pxNetworkEndPoints -> pxNext = ( NetworkEndPoint_t * ) malloc ( sizeof ( NetworkEndPoint_t ) );
187
+ pxNetworkEndPoints -> pxNext = ( NetworkEndPoint_t * ) safeMalloc ( sizeof ( NetworkEndPoint_t ) );
154
188
__CPROVER_assume ( pxNetworkEndPoints -> pxNext != NULL );
155
189
pxNetworkEndPoints -> pxNext -> pxNext = NULL ;
156
190
pxNetworkEndPoints -> pxNext -> pxNetworkInterface = pxNetworkEndPoints -> pxNetworkInterface ;
@@ -160,33 +194,17 @@ void harness()
160
194
pxNetworkEndPoints -> pxNext = NULL ;
161
195
}
162
196
163
- NetworkEndPoint_t * pxNetworkEndPoint_Temp = ( NetworkEndPoint_t * ) malloc ( sizeof ( NetworkEndPoint_t ) );
164
- __CPROVER_assume ( pxNetworkEndPoint_Temp != NULL );
165
- pxNetworkEndPoint_Temp -> pxNext = NULL ;
166
-
167
- /****************************************************************
168
- * Initialize the counter used to bound the number of times
169
- * GetNetworkBufferWithDescriptor can fail.
170
- ****************************************************************/
171
-
172
- #ifdef CBMC_GETNETWORKBUFFER_FAILURE_BOUND
173
- GetNetworkBuffer_failure_count = 0 ;
174
- #endif
175
-
176
- /****************************************************************
177
- * Assume a valid socket in most states of the DHCP state machine.
178
- *
179
- * The socket is created in the eWaitingSendFirstDiscover state.
180
- * xReset==True resets the state to eWaitingSendFirstDiscover.
181
- ****************************************************************/
182
-
183
- if ( !( ( pxNetworkEndPoint_Temp -> xDHCPData .eDHCPState == eInitialWait ) ||
197
+ if ( !( ( pxNetworkEndPoints -> xDHCPData .eDHCPState == eInitialWait ) ||
184
198
( xReset != pdFALSE ) ) )
185
199
{
186
- prvCreateDHCPSocket ( pxNetworkEndPoint_Temp );
200
+ prvCreateDHCPSocket ( pxNetworkEndPoints );
187
201
}
188
202
189
- xDHCPv4Socket = FreeRTOS_socket ( FREERTOS_AF_INET , FREERTOS_SOCK_DGRAM , FREERTOS_IPPROTO_UDP );
203
+ /* Assume vDHCPProcess is only called on IPv4 endpoints which is
204
+ * validated before the call to vDHCPProcess */
205
+ __CPROVER_assume ( pxNetworkEndPoints -> bits .bIPv6 == 0 );
206
+
207
+ vDHCPProcess ( xReset , pxNetworkEndPoints );
190
208
191
- __CPROVER_file_local_FreeRTOS_DHCP_c_vDHCPProcessEndPoint ( xReset , xDoCheck , pxNetworkEndPoint_Temp );
209
+ __CPROVER_file_local_FreeRTOS_DHCP_c_prvCloseDHCPSocket ( pxNetworkEndPoints );
192
210
}
0 commit comments