[修改] 增加freeRTOS
1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
5
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/.gitignore
vendored
Normal file
5
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
cbmc.txt
|
||||
property.xml
|
||||
coverage.xml
|
||||
*.goto
|
||||
**/html/*
|
||||
@ -0,0 +1,133 @@
|
||||
CBMC Proof Infrastructure
|
||||
=========================
|
||||
|
||||
This directory contains automated proofs of the memory safety of various parts
|
||||
of the FreeRTOS codebase. A continuous integration system validates every
|
||||
pull request posted to the repository against these proofs, and developers can
|
||||
also run the proofs on their local machines.
|
||||
|
||||
The proofs are checked using the
|
||||
[C Bounded Model Checker](http://www.cprover.org/cbmc/), an open-source static
|
||||
analysis tool
|
||||
([GitHub repository](https://github.com/diffblue/cbmc)). This README describes
|
||||
how to run the proofs on your local clone of a:FR.
|
||||
|
||||
|
||||
Bulding and running proofs
|
||||
--------------------------
|
||||
|
||||
For historical reasons, some of the proofs are built and run using CMake
|
||||
and CTest. Others use a custom python-based build system. New proofs
|
||||
should use CMake. This README describes how to build and run both kinds
|
||||
of proof.
|
||||
|
||||
|
||||
CMake-based build
|
||||
-----------------
|
||||
|
||||
Follow the CBMC installation instructions below.
|
||||
|
||||
Suppose that the freertos source tree is located at
|
||||
`~/src/freertos` and you wish to build the proofs into
|
||||
`~/build/freertos`. The following three commands build and run
|
||||
the proofs:
|
||||
|
||||
```sh
|
||||
cmake -S~/src/freertos -B~/build/freertos -DCOMPILER=cbmc
|
||||
-DBOARD=windows -DVENDOR=pc
|
||||
cmake --build ~/build/freertos --target all-proofs
|
||||
cd ~/build/freertos && ctest -L cbmc
|
||||
```
|
||||
|
||||
Alternatively, this single command does the same thing, assuming you
|
||||
have the Ninja build tool installed:
|
||||
|
||||
```sh
|
||||
ctest --build-and-test \
|
||||
~/src/freertos \
|
||||
~/build/freertos \
|
||||
--build-target cbmc \
|
||||
--build-generator Ninja \
|
||||
--build-options \
|
||||
-DCOMPILER=cbmc \
|
||||
-DBOARD=windows \
|
||||
-DVENDOR=pc \
|
||||
--test-command ctest -j4 -L cbmc --output-on-failure
|
||||
```
|
||||
|
||||
|
||||
|
||||
Python-based build
|
||||
------------------
|
||||
|
||||
### Prerequisites
|
||||
|
||||
You will need Python 3. On Windows, you will need Visual Studio 2015 or later
|
||||
(in particular, you will need the Developer Command Prompt and NMake). On macOS
|
||||
and Linux, you will need Make.
|
||||
|
||||
|
||||
### Installing CBMC
|
||||
|
||||
- Clone the [CBMC repository](https://github.com/diffblue/cbmc).
|
||||
|
||||
- The canonical compilation and installation instructions are in the
|
||||
[COMPILING.md](https://github.com/diffblue/cbmc/blob/develop/COMPILING.md)
|
||||
file in the CBMC repository; we reproduce the most important steps for
|
||||
Windows users here, but refer to that document if in doubt.
|
||||
- Download and install CMake from the [CMake website](https://cmake.org/download).
|
||||
- Download and install the "git for Windows" package, which also
|
||||
provides the `patch` command, from [here](https://git-scm.com/download/win).
|
||||
- Download the flex and bison for Windows package from
|
||||
[this sourceforge site](https://sourceforge.net/projects/winflexbison).
|
||||
"Install" it by dropping the contents of the entire unzipped
|
||||
package into the top-level CBMC source directory.
|
||||
- Change into the top-level CBMC source directory and run
|
||||
```
|
||||
cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DWITH_JBMC=OFF
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
- Ensure that you can run the programs `cbmc`, `goto-cc` (or `goto-cl`
|
||||
on Windows), and `goto-instrument` from the command line. If you build
|
||||
CBMC with CMake, the programs will have been installed under the
|
||||
`build/bin/Debug` directory under the top-level `cbmc` directory; you
|
||||
should add that directory to your `$PATH`. If you built CBMC using
|
||||
Make, then those programs will have been installed in the `src/cbmc`,
|
||||
`src/goto-cc`, and `src/goto-instrument` directories respectively.
|
||||
|
||||
|
||||
### Setting up the proofs
|
||||
|
||||
Change into the `proofs` directory. On Windows, run
|
||||
```
|
||||
python prepare.py
|
||||
```
|
||||
On macOS or Linux, run
|
||||
```
|
||||
./prepare.py
|
||||
```
|
||||
If you are on a Windows machine but want to generate Linux Makefiles (or vice
|
||||
versa), you can pass the `--system linux` or `--system windows` options to those
|
||||
programs.
|
||||
|
||||
|
||||
### Running the proofs
|
||||
|
||||
Each of the leaf directories under `proofs` is a proof of the memory
|
||||
safety of a single entry point in FreeRTOS. The scripts that you ran in the
|
||||
previous step will have left a Makefile in each of those directories. To
|
||||
run a proof, change into the directory for that proof and run `nmake` on
|
||||
Windows or `make` on Linux or macOS. The proofs may take some time to
|
||||
run; they eventually write their output to `cbmc.txt`, which should have
|
||||
the text `VERIFICATION SUCCESSFUL` at the end.
|
||||
|
||||
|
||||
### Proof directory structure
|
||||
|
||||
This directory contains the following subdirectories:
|
||||
|
||||
- `proofs` contains the proofs run against each pull request
|
||||
- `patches` contains a set of patches that get applied to the codebase prior to
|
||||
running the proofs
|
||||
- `include` and `windows` contain header files used by the proofs.
|
||||
@ -0,0 +1,14 @@
|
||||
execute_process(
|
||||
COMMAND
|
||||
cbmc --cover location --xml-ui
|
||||
${cbmc_flags} ${cbmc_verbosity} ${goto_binary}
|
||||
OUTPUT_FILE ${out_file}
|
||||
ERROR_FILE ${out_file}
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
|
||||
if(NOT (${res} EQUAL 0 OR ${res} EQUAL 10))
|
||||
message(FATAL_ERROR
|
||||
"Unexpected CBMC coverage return code '${res}' for proof ${proof_name}. Log written to ${out_file}."
|
||||
)
|
||||
endif()
|
||||
@ -0,0 +1,14 @@
|
||||
execute_process(
|
||||
COMMAND
|
||||
cbmc --show-properties --unwinding-assertions --xml-ui
|
||||
${cbmc_flags} ${cbmc_verbosity} ${goto_binary}
|
||||
OUTPUT_FILE ${out_file}
|
||||
ERROR_FILE ${out_file}
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
|
||||
if(NOT (${res} EQUAL 0 OR ${res} EQUAL 10))
|
||||
message(FATAL_ERROR
|
||||
"Unexpected CBMC property return code '${res}' for proof ${proof_name}. Log written to ${out_file}."
|
||||
)
|
||||
endif()
|
||||
@ -0,0 +1,14 @@
|
||||
execute_process(
|
||||
COMMAND
|
||||
cbmc --trace --unwinding-assertions
|
||||
${cbmc_flags} ${cbmc_verbosity} ${goto_binary}
|
||||
OUTPUT_FILE ${out_file}
|
||||
ERROR_FILE ${out_file}
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
|
||||
if(NOT (${res} EQUAL 0 OR ${res} EQUAL 10))
|
||||
message(FATAL_ERROR
|
||||
"Unexpected CBMC return code '${res}' for proof ${proof_name}. Log written to ${out_file}."
|
||||
)
|
||||
endif()
|
||||
@ -0,0 +1,2 @@
|
||||
This directory contains include files used by the CBMC proofs:
|
||||
* cbmc.h defines some macros used in the proof test harnesses
|
||||
@ -0,0 +1,5 @@
|
||||
eFrameProcessingResult_t publicProcessIPPacket( IPPacket_t * const pxIPPacket,
|
||||
NetworkBufferDescriptor_t * const pxNetworkBuffer )
|
||||
{
|
||||
prvProcessIPPacket( pxIPPacket, pxNetworkBuffer );
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
int32_t publicTCPPrepareSend( FreeRTOS_Socket_t * pxSocket,
|
||||
NetworkBufferDescriptor_t ** ppxNetworkBuffer,
|
||||
UBaseType_t uxOptionsLength )
|
||||
{
|
||||
prvTCPPrepareSend( pxSocket, ppxNetworkBuffer, uxOptionsLength );
|
||||
}
|
||||
|
||||
BaseType_t publicTCPHandleState( FreeRTOS_Socket_t * pxSocket,
|
||||
NetworkBufferDescriptor_t ** ppxNetworkBuffer )
|
||||
{
|
||||
prvTCPHandleState( pxSocket, ppxNetworkBuffer );
|
||||
}
|
||||
|
||||
void publicTCPReturnPacket( FreeRTOS_Socket_t * pxSocket,
|
||||
NetworkBufferDescriptor_t * pxNetworkBuffer,
|
||||
uint32_t ulLen,
|
||||
BaseType_t xReleaseAfterSend )
|
||||
{
|
||||
prvTCPReturnPacket( pxSocket, pxNetworkBuffer, ulLen, xReleaseAfterSend );
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
/*
|
||||
* CBMC models a pointer as an object id and an offset into that
|
||||
* object. The top bits of a pointer encode the object id and the
|
||||
* remaining bits encode the offset. This means there is a bound on
|
||||
* the maximum offset into an object in CBMC, and hence a bound on the
|
||||
* size of objects in CBMC.
|
||||
*/
|
||||
#define CBMC_BITS 7
|
||||
#define CBMC_MAX_OBJECT_SIZE ( 0xFFFFFFFF >> ( CBMC_BITS + 1 ) )
|
||||
|
||||
#define IMPLIES( a, b ) ( !( a ) || ( b ) )
|
||||
|
||||
BaseType_t nondet_basetype();
|
||||
UBaseType_t nondet_ubasetype();
|
||||
TickType_t nondet_ticktype();
|
||||
int32_t nondet_int32();
|
||||
uint32_t nondet_uint32();
|
||||
size_t nondet_sizet();
|
||||
|
||||
#define nondet_BaseType() nondet_basetype()
|
||||
|
||||
void * safeMalloc( size_t size );
|
||||
|
||||
|
||||
enum CBMC_LOOP_CONDITION
|
||||
{
|
||||
CBMC_LOOP_BREAK, CBMC_LOOP_CONTINUE, CBMC_LOOP_RETURN
|
||||
};
|
||||
|
||||
/* CBMC specification: capture old value for precondition and */
|
||||
/* postcondition checking */
|
||||
|
||||
#define OLDVAL( var ) _old_ ## var
|
||||
#define SAVE_OLDVAL( var, typ ) const typ OLDVAL( var ) = var
|
||||
|
||||
/* CBMC specification: capture old value for values passed by */
|
||||
/* reference in function abstractions */
|
||||
|
||||
#define OBJ( var ) ( * var )
|
||||
#define OLDOBJ( var ) _oldobj_ ## var
|
||||
#define SAVE_OLDOBJ( var, typ ) const typ OLDOBJ( var ) = OBJ( var )
|
||||
|
||||
/* CBMC debugging: printfs for expressions */
|
||||
|
||||
#define __CPROVER_printf( var ) { uint32_t ValueOf_ ## var = ( uint32_t ) var; }
|
||||
#define __CPROVER_printf2( str, exp ) { uint32_t ValueOf_ ## str = ( uint32_t ) ( exp ); }
|
||||
|
||||
/* CBMC debugging: printfs for pointer expressions */
|
||||
|
||||
#define __CPROVER_printf_ptr( var ) { uint8_t * ValueOf_ ## var = ( uint8_t * ) var; }
|
||||
#define __CPROVER_printf2_ptr( str, exp ) { uint8_t * ValueOf_ ## str = ( uint8_t * ) ( exp ); }
|
||||
|
||||
/*
|
||||
* An assertion that pvPortMalloc returns NULL when asked to allocate 0 bytes.
|
||||
* This assertion is used in some of the TaskPool proofs.
|
||||
*/
|
||||
#define __CPROVER_assert_zero_allocation() \
|
||||
__CPROVER_assert( pvPortMalloc( 0 ) == NULL, \
|
||||
"pvPortMalloc allows zero-allocated memory." )
|
||||
|
||||
/*
|
||||
* A stub for pvPortMalloc that nondeterministically chooses to return
|
||||
* either NULL or an allocation of the requested space. The stub is
|
||||
* guaranteed to return NULL when asked to allocate 0 bytes.
|
||||
* This stub is used in some of the TaskPool proofs.
|
||||
*/
|
||||
void * pvPortMalloc( size_t xWantedSize )
|
||||
{
|
||||
if( xWantedSize == 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nondet_bool() ? malloc( xWantedSize ) : NULL;
|
||||
}
|
||||
|
||||
void vPortFree( void * pv )
|
||||
{
|
||||
( void ) pv;
|
||||
free( pv );
|
||||
}
|
||||
@ -0,0 +1,173 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "queue_datastructure.h"
|
||||
|
||||
#ifndef CBMC_OBJECT_BITS
|
||||
#define CBMC_OBJECT_BITS 7
|
||||
#endif
|
||||
|
||||
#ifndef CBMC_OBJECT_MAX_SIZE
|
||||
#define CBMC_OBJECT_MAX_SIZE ( UINT32_MAX >> ( CBMC_OBJECT_BITS + 1 ) )
|
||||
#endif
|
||||
|
||||
/* Using prvCopyDataToQueue together with prvNotifyQueueSetContainer
|
||||
* leads to a problem space explosion. Therefore, we use this stub
|
||||
* and a separated proof on prvCopyDataToQueue to deal with it.
|
||||
* As prvNotifyQueueSetContainer is disabled if configUSE_QUEUE_SETS != 1,
|
||||
* in other cases the original implementation should be used. */
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
|
||||
const void * pvItemToQueue,
|
||||
const BaseType_t xPosition )
|
||||
{
|
||||
if( pxQueue->uxItemSize > ( UBaseType_t ) 0 )
|
||||
{
|
||||
__CPROVER_assert( __CPROVER_r_ok( pvItemToQueue, ( size_t ) pxQueue->uxItemSize ), "pvItemToQueue region must be readable" );
|
||||
|
||||
if( xPosition == queueSEND_TO_BACK )
|
||||
{
|
||||
__CPROVER_assert( __CPROVER_w_ok( ( void * ) pxQueue->pcWriteTo, ( size_t ) pxQueue->uxItemSize ), "pxQueue->pcWriteTo region must be writable" );
|
||||
}
|
||||
else
|
||||
{
|
||||
__CPROVER_assert( __CPROVER_w_ok( ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ), "pxQueue->u.xQueue.pcReadFrom region must be writable" );
|
||||
}
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nondet_BaseType_t();
|
||||
}
|
||||
}
|
||||
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
|
||||
|
||||
/* xQueueCreateSet is compiled out if configUSE_QUEUE_SETS != 1.*/
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
QueueSetHandle_t xUnconstrainedQueueSet()
|
||||
{
|
||||
UBaseType_t uxEventQueueLength = 2;
|
||||
QueueSetHandle_t xSet = xQueueCreateSet( uxEventQueueLength );
|
||||
|
||||
if( xSet )
|
||||
{
|
||||
xSet->cTxLock = nondet_int8_t();
|
||||
__CPROVER_assume( xSet->cTxLock != 127 );
|
||||
xSet->cRxLock = nondet_int8_t();
|
||||
xSet->uxMessagesWaiting = nondet_UBaseType_t();
|
||||
xSet->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t();
|
||||
|
||||
/* This is an invariant checked with a couple of asserts in the code base.
|
||||
* If it is false from the beginning, the CBMC proofs are not able to succeed*/
|
||||
__CPROVER_assume( xSet->uxMessagesWaiting < xSet->uxLength );
|
||||
xSet->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t();
|
||||
}
|
||||
|
||||
return xSet;
|
||||
}
|
||||
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
|
||||
|
||||
/* Create a mostly unconstrained Queue but bound the max item size.
|
||||
* This is required for performance reasons in CBMC at the moment. */
|
||||
QueueHandle_t xUnconstrainedQueueBoundedItemSize( UBaseType_t uxItemSizeBound )
|
||||
{
|
||||
UBaseType_t uxQueueLength;
|
||||
UBaseType_t uxItemSize;
|
||||
uint8_t ucQueueType;
|
||||
|
||||
__CPROVER_assume( uxQueueLength > 0 );
|
||||
__CPROVER_assume( uxItemSize < uxItemSizeBound );
|
||||
|
||||
/* QueueGenericCreate method does not check for multiplication overflow */
|
||||
size_t uxQueueStorageSize;
|
||||
|
||||
__CPROVER_assume( uxQueueStorageSize < CBMC_OBJECT_MAX_SIZE );
|
||||
__CPROVER_assume( uxItemSize < uxQueueStorageSize / uxQueueLength );
|
||||
|
||||
QueueHandle_t xQueue =
|
||||
xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType );
|
||||
|
||||
if( xQueue )
|
||||
{
|
||||
xQueue->cTxLock = nondet_int8_t();
|
||||
__CPROVER_assume( xQueue->cTxLock != 127 );
|
||||
xQueue->cRxLock = nondet_int8_t();
|
||||
xQueue->uxMessagesWaiting = nondet_UBaseType_t();
|
||||
|
||||
/* This is an invariant checked with a couple of asserts in the code base.
|
||||
* If it is false from the beginning, the CBMC proofs are not able to succeed*/
|
||||
__CPROVER_assume( xQueue->uxMessagesWaiting < xQueue->uxLength );
|
||||
xQueue->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t();
|
||||
xQueue->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t();
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
xQueueAddToSet( xQueue, xUnconstrainedQueueSet() );
|
||||
#endif
|
||||
}
|
||||
|
||||
return xQueue;
|
||||
}
|
||||
|
||||
/* Create a mostly unconstrained Queue */
|
||||
QueueHandle_t xUnconstrainedQueue( void )
|
||||
{
|
||||
UBaseType_t uxQueueLength;
|
||||
UBaseType_t uxItemSize;
|
||||
uint8_t ucQueueType;
|
||||
|
||||
__CPROVER_assume( uxQueueLength > 0 );
|
||||
|
||||
/* QueueGenericCreate method does not check for multiplication overflow */
|
||||
size_t uxQueueStorageSize;
|
||||
|
||||
__CPROVER_assume( uxQueueStorageSize < CBMC_OBJECT_MAX_SIZE );
|
||||
__CPROVER_assume( uxItemSize < uxQueueStorageSize / uxQueueLength );
|
||||
|
||||
QueueHandle_t xQueue =
|
||||
xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType );
|
||||
|
||||
if( xQueue )
|
||||
{
|
||||
xQueue->cTxLock = nondet_int8_t();
|
||||
__CPROVER_assume( xQueue->cTxLock != 127 );
|
||||
xQueue->cRxLock = nondet_int8_t();
|
||||
xQueue->uxMessagesWaiting = nondet_UBaseType_t();
|
||||
|
||||
/* This is an invariant checked with a couple of asserts in the code base.
|
||||
* If it is false from the beginning, the CBMC proofs are not able to succeed*/
|
||||
__CPROVER_assume( xQueue->uxMessagesWaiting < xQueue->uxLength );
|
||||
xQueue->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t();
|
||||
xQueue->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t();
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
xQueueAddToSet( xQueue, xUnconstrainedQueueSet() );
|
||||
#endif
|
||||
}
|
||||
|
||||
return xQueue;
|
||||
}
|
||||
|
||||
/* Create a mostly unconstrained Mutex */
|
||||
QueueHandle_t xUnconstrainedMutex( void )
|
||||
{
|
||||
uint8_t ucQueueType;
|
||||
QueueHandle_t xQueue =
|
||||
xQueueCreateMutex( ucQueueType );
|
||||
|
||||
if( xQueue )
|
||||
{
|
||||
xQueue->cTxLock = nondet_int8_t();
|
||||
__CPROVER_assume( xQueue->cTxLock != 127 );
|
||||
xQueue->cRxLock = nondet_int8_t();
|
||||
xQueue->uxMessagesWaiting = nondet_UBaseType_t();
|
||||
|
||||
/* This is an invariant checked with a couple of asserts in the code base.
|
||||
* If it is false from the beginning, the CBMC proofs are not able to succeed*/
|
||||
__CPROVER_assume( xQueue->uxMessagesWaiting < xQueue->uxLength );
|
||||
xQueue->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t();
|
||||
xQueue->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t();
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
xQueueAddToSet( xQueue, xUnconstrainedQueueSet() );
|
||||
#endif
|
||||
}
|
||||
|
||||
return xQueue;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
#ifndef INC_TASK_STUBS_H
|
||||
#define INC_TASK_STUBS_H
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
BaseType_t xState;
|
||||
void vInitTaskCheckForTimeOut( BaseType_t maxCounter,
|
||||
BaseType_t maxCounter_limit );
|
||||
|
||||
#endif /* INC_TASK_STUBS_H */
|
||||
2
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/.gitattributes
vendored
Normal file
2
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# It seems git apply does not want crlf line endings on Windows
|
||||
*.patch eol=lf
|
||||
2
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/.gitignore
vendored
Normal file
2
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
auto_patch*
|
||||
patched
|
||||
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V3.1.0
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
* http://www.freertos.org/a00110.html
|
||||
*
|
||||
* The bottom of this file contains some constants specific to running the UDP
|
||||
* stack in this demo. Constants specific to FreeRTOS+TCP itself (rather than
|
||||
* the demo) are contained in FreeRTOSIPConfig.h.
|
||||
*----------------------------------------------------------*/
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configMAX_PRIORITIES ( 7 )
|
||||
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048U * 1024U ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 15 )
|
||||
#ifndef configUSE_16_BIT_TICKS
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#endif
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#ifndef configUSE_MUTEXES
|
||||
#define configUSE_MUTEXES 1
|
||||
#endif
|
||||
#ifndef configUSE_RECURSIVE_MUTEXES
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#endif
|
||||
#define configQUEUE_REGISTRY_SIZE 0
|
||||
#define configUSE_APPLICATION_TASK_TAG 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_ALTERNATIVE_API 0
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 3 /* FreeRTOS+FAT requires 2 pointers if a CWD is supported. */
|
||||
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#ifndef configUSE_TICK_HOOK
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#endif
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */
|
||||
|
||||
/* Software timer related definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||
#define configTIMER_QUEUE_LENGTH 5
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
|
||||
/* Event group related definitions. */
|
||||
#define configUSE_EVENT_GROUPS 1
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* Memory allocation strategy. */
|
||||
#ifndef configSUPPORT_DYNAMIC_ALLOCATION
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#endif
|
||||
#ifndef configSUPPORT_STATIC_ALLOCATION
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
* to exclude the API function. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 0
|
||||
#ifndef INCLUDE_vTaskSuspend
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#endif
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#ifndef INCLUDE_xTaskGetSchedulerState
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#endif
|
||||
#define INCLUDE_xTimerGetTimerTaskHandle 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_xQueueGetMutexHolder 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xEventGroupSetBitsFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
|
||||
/* This demo makes use of one or more example stats formatting functions. These
|
||||
* format the raw data provided by the uxTaskGetSystemState() function in to human
|
||||
* readable ASCII form. See the notes in the implementation of vTaskList() within
|
||||
* FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS
|
||||
* is set to 2 so the formatting functions are included without the stdio.h being
|
||||
* included in tasks.c. That is because this project defines its own sprintf()
|
||||
* functions. */
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||
|
||||
/* Assert call defined for debug builds. */
|
||||
extern void vAssertCalled( const char * pcFile,
|
||||
uint32_t ulLine );
|
||||
#ifndef configASSERT
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
|
||||
#endif
|
||||
|
||||
/* Remove logging in formal verification */
|
||||
#define configPRINTF( X )
|
||||
|
||||
/* Non-format version thread-safe print. */
|
||||
#define configPRINT_STRING( X )
|
||||
|
||||
/* Application specific definitions follow. **********************************/
|
||||
|
||||
/* If configINCLUDE_DEMO_DEBUG_STATS is set to one, then a few basic IP trace
|
||||
* macros are defined to gather some UDP stack statistics that can then be viewed
|
||||
* through the CLI interface. */
|
||||
#define configINCLUDE_DEMO_DEBUG_STATS 1
|
||||
|
||||
/* The size of the global output buffer that is available for use when there
|
||||
* are multiple command interpreters running at once (for example, one on a UART
|
||||
* and one on TCP/IP). This is done to prevent an output buffer being defined by
|
||||
* each implementation - which would waste RAM. In this case, there is only one
|
||||
* command interpreter running, and it has its own local output buffer, so the
|
||||
* global buffer is just set to be one byte long as it is not used and should not
|
||||
* take up unnecessary RAM. */
|
||||
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1
|
||||
|
||||
/* Only used when running in the FreeRTOS Windows simulator. Defines the
|
||||
* priority of the task used to simulate Ethernet interrupts. */
|
||||
#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||
|
||||
/* This demo creates a virtual network connection by accessing the raw Ethernet
|
||||
* or WiFi data to and from a real network connection. Many computers have more
|
||||
* than one real network port, and configNETWORK_INTERFACE_TO_USE is used to tell
|
||||
* the demo which real port should be used to create the virtual port. The ports
|
||||
* available are displayed on the console when the application is executed. For
|
||||
* example, on my development laptop setting configNETWORK_INTERFACE_TO_USE to 4
|
||||
* results in the wired network being used, while setting
|
||||
* configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being
|
||||
* used. */
|
||||
#define configNETWORK_INTERFACE_TO_USE ( 0L )
|
||||
|
||||
/* The address of an echo server that will be used by the two demo echo client
|
||||
* tasks:
|
||||
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html,
|
||||
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html. */
|
||||
#define configECHO_SERVER_ADDR0 192
|
||||
#define configECHO_SERVER_ADDR1 168
|
||||
#define configECHO_SERVER_ADDR2 2
|
||||
#define configECHO_SERVER_ADDR3 6
|
||||
#define configTCP_ECHO_CLIENT_PORT 7
|
||||
|
||||
/* Default MAC address configuration. The demo creates a virtual network
|
||||
* connection that uses this MAC address by accessing the raw Ethernet/WiFi data
|
||||
* to and from a real network connection on the host PC. See the
|
||||
* configNETWORK_INTERFACE_TO_USE definition above for information on how to
|
||||
* configure the real network connection to use. */
|
||||
#define configMAC_ADDR0 0x00
|
||||
#define configMAC_ADDR1 0x11
|
||||
#define configMAC_ADDR2 0x22
|
||||
#define configMAC_ADDR3 0x33
|
||||
#define configMAC_ADDR4 0x44
|
||||
#define configMAC_ADDR5 0x21
|
||||
|
||||
/* Default IP address configuration. Used in ipconfigUSE_DHCP is set to 0, or
|
||||
* ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */
|
||||
#define configIP_ADDR0 192
|
||||
#define configIP_ADDR1 168
|
||||
#define configIP_ADDR2 0
|
||||
#define configIP_ADDR3 105
|
||||
|
||||
/* Default gateway IP address configuration. Used in ipconfigUSE_DHCP is set to
|
||||
* 0, or ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */
|
||||
#define configGATEWAY_ADDR0 192
|
||||
#define configGATEWAY_ADDR1 168
|
||||
#define configGATEWAY_ADDR2 0
|
||||
#define configGATEWAY_ADDR3 1
|
||||
|
||||
/* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and
|
||||
* 208.67.220.220. Used in ipconfigUSE_DHCP is set to 0, or ipconfigUSE_DHCP is
|
||||
* set to 1 but a DNS server cannot be contacted.*/
|
||||
#define configDNS_SERVER_ADDR0 208
|
||||
#define configDNS_SERVER_ADDR1 67
|
||||
#define configDNS_SERVER_ADDR2 222
|
||||
#define configDNS_SERVER_ADDR3 222
|
||||
|
||||
/* Default netmask configuration. Used in ipconfigUSE_DHCP is set to 0, or
|
||||
* ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */
|
||||
#define configNET_MASK0 255
|
||||
#define configNET_MASK1 255
|
||||
#define configNET_MASK2 255
|
||||
#define configNET_MASK3 0
|
||||
|
||||
/* The UDP port to which print messages are sent. */
|
||||
#define configPRINT_PORT ( 15000 )
|
||||
|
||||
#define configPROFILING ( 0 )
|
||||
|
||||
/* Pseudo random number generator used by some demo tasks. */
|
||||
extern uint32_t ulRand();
|
||||
#define configRAND32() ulRand()
|
||||
|
||||
/* The platform that FreeRTOS is running on. */
|
||||
#define configPLATFORM_NAME "WinSim"
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
@ -0,0 +1,329 @@
|
||||
/*
|
||||
* FreeRTOS+TCP V3.1.0
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* See the following URL for configuration information.
|
||||
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef FREERTOS_IP_CONFIG_H
|
||||
#define FREERTOS_IP_CONFIG_H
|
||||
|
||||
/* Set to 1 to print out debug messages. If ipconfigHAS_DEBUG_PRINTF is set to
|
||||
* 1 then FreeRTOS_debug_printf should be defined to the function used to print
|
||||
* out the debugging messages. */
|
||||
#ifndef ipconfigHAS_DEBUG_PRINTF
|
||||
#define ipconfigHAS_DEBUG_PRINTF 0
|
||||
#endif
|
||||
#if ( ipconfigHAS_DEBUG_PRINTF == 1 )
|
||||
#define FreeRTOS_debug_printf( X ) configPRINTF( X )
|
||||
#endif
|
||||
|
||||
/* Set to 1 to print out non debugging messages, for example the output of the
|
||||
* FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1
|
||||
* then FreeRTOS_printf should be set to the function used to print out the
|
||||
* messages. */
|
||||
#define FreeRTOS_printf( X )
|
||||
|
||||
|
||||
/* Define the byte order of the target MCU (the MCU FreeRTOS+TCP is executing
|
||||
* on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */
|
||||
#ifndef ipconfigBYTE_ORDER
|
||||
#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/* If the network card/driver includes checksum offloading (IP/TCP/UDP checksums)
|
||||
* then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software
|
||||
* stack repeating the checksum calculations. */
|
||||
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
|
||||
|
||||
/* Several API's will block until the result is known, or the action has been
|
||||
* performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be
|
||||
* set per socket, using setsockopt(). If not set, the times below will be
|
||||
* used as defaults. */
|
||||
#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 )
|
||||
#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 )
|
||||
|
||||
/* Include support for DNS caching. For TCP, having a small DNS cache is very
|
||||
* useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low
|
||||
* and also DNS may use small timeouts. If a DNS reply comes in after the DNS
|
||||
* socket has been destroyed, the result will be stored into the cache. The next
|
||||
* call to FreeRTOS_gethostbyname() will return immediately, without even creating
|
||||
* a socket. */
|
||||
#ifndef ipconfigUSE_DNS_CACHE
|
||||
#define ipconfigUSE_DNS_CACHE ( 1 )
|
||||
#endif
|
||||
#define ipconfigDNS_REQUEST_ATTEMPTS ( 2 )
|
||||
|
||||
/* The IP stack executes it its own task (although any application task can make
|
||||
* use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY
|
||||
* sets the priority of the task that executes the IP stack. The priority is a
|
||||
* standard FreeRTOS task priority so can take any value from 0 (the lowest
|
||||
* priority) to (configMAX_PRIORITIES - 1) (the highest priority).
|
||||
* configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in
|
||||
* FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to
|
||||
* the priority assigned to the task executing the IP stack relative to the
|
||||
* priority assigned to tasks that use the IP stack. */
|
||||
#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
|
||||
|
||||
/* The size, in words (not bytes), of the stack allocated to the FreeRTOS+TCP
|
||||
* task. This setting is less important when the FreeRTOS Win32 simulator is used
|
||||
* as the Win32 simulator only stores a fixed amount of information on the task
|
||||
* stack. FreeRTOS includes optional stack overflow detection, see:
|
||||
* http://www.freertos.org/Stacks-and-stack-overflow-checking.html. */
|
||||
#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 )
|
||||
|
||||
/* ipconfigRAND32() is called by the IP stack to generate random numbers for
|
||||
* things such as a DHCP transaction number or initial sequence number. Random
|
||||
* number generation is performed via this macro to allow applications to use their
|
||||
* own random number generation method. For example, it might be possible to
|
||||
* generate a random number by sampling noise on an analogue input. */
|
||||
extern uint32_t ulRand();
|
||||
#define ipconfigRAND32() ulRand()
|
||||
|
||||
/* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the
|
||||
* network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK
|
||||
* is not set to 1 then the network event hook will never be called. See:
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml.
|
||||
*/
|
||||
#define ipconfigUSE_NETWORK_EVENT_HOOK 1
|
||||
|
||||
/* Sockets have a send block time attribute. If FreeRTOS_sendto() is called but
|
||||
* a network buffer cannot be obtained then the calling task is held in the Blocked
|
||||
* state (so other tasks can continue to executed) until either a network buffer
|
||||
* becomes available or the send block time expires. If the send block time expires
|
||||
* then the send operation is aborted. The maximum allowable send block time is
|
||||
* capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the
|
||||
* maximum allowable send block time prevents prevents a deadlock occurring when
|
||||
* all the network buffers are in use and the tasks that process (and subsequently
|
||||
* free) the network buffers are themselves blocked waiting for a network buffer.
|
||||
* ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in
|
||||
* milliseconds can be converted to a time in ticks by dividing the time in
|
||||
* milliseconds by portTICK_PERIOD_MS. */
|
||||
#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000U / portTICK_PERIOD_MS )
|
||||
|
||||
/* If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP
|
||||
* address, netmask, DNS server address and gateway address from a DHCP server. If
|
||||
* ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The
|
||||
* stack will revert to using the static IP address even when ipconfigUSE_DHCP is
|
||||
* set to 1 if a valid configuration cannot be obtained from a DHCP server for any
|
||||
* reason. The static configuration used is that passed into the stack by the
|
||||
* FreeRTOS_IPInit() function call. */
|
||||
#define ipconfigUSE_DHCP 1
|
||||
#define ipconfigDHCP_REGISTER_HOSTNAME 1
|
||||
#define ipconfigDHCP_USES_UNICAST 1
|
||||
|
||||
/* If ipconfigDHCP_USES_USER_HOOK is set to 1 then the application writer must
|
||||
* provide an implementation of the DHCP callback function,
|
||||
* xApplicationDHCPUserHook(). */
|
||||
#define ipconfigUSE_DHCP_HOOK 0
|
||||
|
||||
/* When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at
|
||||
* increasing time intervals until either a reply is received from a DHCP server
|
||||
* and accepted, or the interval between transmissions reaches
|
||||
* ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the
|
||||
* static IP address passed as a parameter to FreeRTOS_IPInit() if the
|
||||
* re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without
|
||||
* a DHCP reply being received. */
|
||||
#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD \
|
||||
( 120000U / portTICK_PERIOD_MS )
|
||||
|
||||
/* The ARP cache is a table that maps IP addresses to MAC addresses. The IP
|
||||
* stack can only send a UDP message to a remove IP address if it knowns the MAC
|
||||
* address associated with the IP address, or the MAC address of the router used to
|
||||
* contact the remote IP address. When a UDP message is received from a remote IP
|
||||
* address the MAC address and IP address are added to the ARP cache. When a UDP
|
||||
* message is sent to a remote IP address that does not already appear in the ARP
|
||||
* cache then the UDP message is replaced by a ARP message that solicits the
|
||||
* required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum
|
||||
* number of entries that can exist in the ARP table at any one time. */
|
||||
#ifndef ipconfigARP_CACHE_ENTRIES
|
||||
#define ipconfigARP_CACHE_ENTRIES 6
|
||||
#endif
|
||||
|
||||
/* ARP requests that do not result in an ARP response will be re-transmitted a
|
||||
* maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is
|
||||
* aborted. */
|
||||
#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 )
|
||||
|
||||
/* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP
|
||||
* table being created or refreshed and the entry being removed because it is stale.
|
||||
* New ARP requests are sent for ARP cache entries that are nearing their maximum
|
||||
* age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is
|
||||
* equal to 1500 seconds (or 25 minutes). */
|
||||
#define ipconfigMAX_ARP_AGE 150
|
||||
|
||||
/* Implementing FreeRTOS_inet_addr() necessitates the use of string handling
|
||||
* routines, which are relatively large. To save code space the full
|
||||
* FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster
|
||||
* alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr()
|
||||
* takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter.
|
||||
* FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets
|
||||
* (for example, 192, 168, 0, 1) as its parameters. If
|
||||
* ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and
|
||||
* FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is
|
||||
* not set to 1 then only FreeRTOS_indet_addr_quick() is available. */
|
||||
#define ipconfigINCLUDE_FULL_INET_ADDR 1
|
||||
|
||||
/* ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS defines the total number of network buffer that
|
||||
* are available to the IP stack. The total number of network buffers is limited
|
||||
* to ensure the total amount of RAM that can be consumed by the IP stack is capped
|
||||
* to a pre-determinable value. */
|
||||
#ifndef ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS
|
||||
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60
|
||||
#endif
|
||||
|
||||
/* A FreeRTOS queue is used to send events from application tasks to the IP
|
||||
* stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can
|
||||
* be queued for processing at any one time. The event queue must be a minimum of
|
||||
* 5 greater than the total number of network buffers. */
|
||||
#define ipconfigEVENT_QUEUE_LENGTH \
|
||||
( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
|
||||
|
||||
/* The address of a socket is the combination of its IP address and its port
|
||||
* number. FreeRTOS_bind() is used to manually allocate a port number to a socket
|
||||
* (to 'bind' the socket to a port), but manual binding is not normally necessary
|
||||
* for client sockets (those sockets that initiate outgoing connections rather than
|
||||
* wait for incoming connections on a known port number). If
|
||||
* ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling
|
||||
* FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP
|
||||
* stack automatically binding the socket to a port number from the range
|
||||
* socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If
|
||||
* ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto()
|
||||
* on a socket that has not yet been bound will result in the send operation being
|
||||
* aborted. */
|
||||
#ifndef ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND
|
||||
#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
|
||||
#endif
|
||||
|
||||
/* Defines the Time To Live (TTL) values used in outgoing UDP packets. */
|
||||
#define ipconfigUDP_TIME_TO_LIVE 128
|
||||
/* Also defined in FreeRTOSIPConfigDefaults.h. */
|
||||
#define ipconfigTCP_TIME_TO_LIVE 128
|
||||
|
||||
/* USE_TCP: Use TCP and all its features. */
|
||||
#ifndef ipconfigUSE_TCP
|
||||
#define ipconfigUSE_TCP ( 1 )
|
||||
#endif
|
||||
|
||||
/* USE_WIN: Let TCP use windowing mechanism. */
|
||||
#ifndef ipconfigUSE_TCP_WIN
|
||||
#define ipconfigUSE_TCP_WIN ( 1 )
|
||||
#endif
|
||||
|
||||
/* The MTU is the maximum number of bytes the payload of a network frame can
|
||||
* contain. For normal Ethernet V2 frames the maximum MTU is 1500. Setting a
|
||||
* lower value can save RAM, depending on the buffer management scheme used. If
|
||||
* ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is 1 then (ipconfigNETWORK_MTU - 28) must
|
||||
* be divisible by 8. */
|
||||
#define ipconfigNETWORK_MTU 1500U
|
||||
|
||||
/* Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used
|
||||
* through the FreeRTOS_gethostbyname() API function. */
|
||||
#define ipconfigUSE_DNS 1
|
||||
|
||||
/* If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will
|
||||
* generate replies to incoming ICMP echo (ping) requests. */
|
||||
#define ipconfigREPLY_TO_INCOMING_PINGS 1
|
||||
|
||||
/* If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the
|
||||
* FreeRTOS_SendPingRequest() API function is available. */
|
||||
#ifndef ipconfigSUPPORT_OUTGOING_PINGS
|
||||
#define ipconfigSUPPORT_OUTGOING_PINGS 0
|
||||
#endif
|
||||
|
||||
/* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select()
|
||||
* (and associated) API function is available. */
|
||||
#ifndef ipconfigSUPPORT_SELECT_FUNCTION
|
||||
#define ipconfigSUPPORT_SELECT_FUNCTION 0
|
||||
#endif
|
||||
|
||||
/* If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames
|
||||
* that are not in Ethernet II format will be dropped. This option is included for
|
||||
* potential future IP stack developments. */
|
||||
#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
|
||||
|
||||
/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the
|
||||
* responsibility of the Ethernet interface to filter out packets that are of no
|
||||
* interest. If the Ethernet interface does not implement this functionality, then
|
||||
* set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack
|
||||
* perform the filtering instead (it is much less efficient for the stack to do it
|
||||
* because the packet will already have been passed into the stack). If the
|
||||
* Ethernet driver does all the necessary filtering in hardware then software
|
||||
* filtering can be removed by using a value other than 1 or 0. */
|
||||
#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
|
||||
|
||||
/* The windows simulator cannot really simulate MAC interrupts, and needs to
|
||||
* block occasionally to allow other tasks to run. */
|
||||
#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS )
|
||||
|
||||
/* Advanced only: in order to access 32-bit fields in the IP packets with
|
||||
* 32-bit memory instructions, all packets will be stored 32-bit-aligned,
|
||||
* plus 16-bits. This has to do with the contents of the IP-packets: all
|
||||
* 32-bit fields are 32-bit-aligned, plus 16-bit. */
|
||||
#define ipconfigPACKET_FILLER_SIZE 2U
|
||||
|
||||
/* Define the size of the pool of TCP window descriptors. On the average, each
|
||||
* TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6
|
||||
* outstanding packets (for Rx and Tx). When using up to 10 TP sockets
|
||||
* simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */
|
||||
#define ipconfigTCP_WIN_SEG_COUNT 240
|
||||
|
||||
/* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed
|
||||
* maximum size. Define the size of Rx buffer for TCP sockets. */
|
||||
#define ipconfigTCP_RX_BUFFER_LENGTH ( 10000 )
|
||||
|
||||
/* Define the size of Tx buffer for TCP sockets. */
|
||||
#define ipconfigTCP_TX_BUFFER_LENGTH ( 10000 )
|
||||
|
||||
/* When using call-back handlers, the driver may check if the handler points to
|
||||
* real program memory (RAM or flash) or just has a random non-zero value. */
|
||||
#define ipconfigIS_VALID_PROG_ADDRESS( x ) ( ( x ) != NULL )
|
||||
|
||||
/* Include support for TCP keep-alive messages. */
|
||||
#define ipconfigTCP_KEEP_ALIVE ( 1 )
|
||||
#define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 ) /* Seconds. */
|
||||
|
||||
/* The socket semaphore is used to unblock the MQTT task. */
|
||||
#ifndef ipconfigSOCKET_HAS_USER_SEMAPHORE
|
||||
#define ipconfigSOCKET_HAS_USER_SEMAPHORE ( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef ipconfigSOCKET_HAS_USER_WAKE_CALLBACK
|
||||
#define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK ( 1 )
|
||||
#endif
|
||||
#define ipconfigUSE_CALLBACKS ( 0 )
|
||||
|
||||
|
||||
#define portINLINE __inline
|
||||
|
||||
void vApplicationMQTTGetKeys( const char ** ppcRootCA,
|
||||
const char ** ppcClientCert,
|
||||
const char ** ppcClientPrivateKey );
|
||||
|
||||
#endif /* FREERTOS_IP_CONFIG_H */
|
||||
@ -0,0 +1,24 @@
|
||||
BRANCH=freertos
|
||||
|
||||
PATCHED=patched
|
||||
|
||||
default:
|
||||
git format-patch $(BRANCH)..$(BRANCH)-cbmc-patches
|
||||
|
||||
patch:
|
||||
if [ ! -f $(PATCHED) ]; then \
|
||||
for p in *.patch; do \
|
||||
(cd ../../..; patch -p1 < CBMC/patches/$${p}) \
|
||||
done; \
|
||||
cat > $(PATCHED) < /dev/null; \
|
||||
fi
|
||||
|
||||
unpatch:
|
||||
git checkout ../../../lib
|
||||
$(RM) $(PATCHED)
|
||||
|
||||
#patching file lib/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h
|
||||
#patching file lib/include/private/list.h
|
||||
#patching file lib/FreeRTOS-Plus-TCP/source/FreeRTOS_DHCP.c
|
||||
#patching file lib/FreeRTOS-Plus-TCP/source/FreeRTOS_DNS.c
|
||||
#patching file lib/FreeRTOS-Plus-TCP/source/FreeRTOS_TCP_WIN.c
|
||||
@ -0,0 +1,6 @@
|
||||
This directory includes patches to FreeRTOS required to run the CBMC proofs.
|
||||
|
||||
The patches fall into three classes:
|
||||
* First is a refactoring of prvCheckOptions
|
||||
* Second is the removal of static attributes from some functions
|
||||
* Third is two patches dealing with shortcomings of CBMC that should be removed soon.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
241
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/compute_patch.py
Executable file
241
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/compute_patch.py
Executable file
@ -0,0 +1,241 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Generation of patches for CBMC proofs.
|
||||
#
|
||||
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import textwrap
|
||||
import unittest
|
||||
|
||||
from patches_constants import PATCHES_DIR
|
||||
from patches_constants import HEADERS
|
||||
|
||||
|
||||
DEFINE_REGEX_MAKEFILE = re.compile(r"(?:['\"])?([\w]+)")
|
||||
DEFINE_REGEX_HEADER = re.compile(r"\s*#\s*define\s*([\w]+)")
|
||||
|
||||
class DirtyGitError(Exception):
|
||||
pass
|
||||
|
||||
class PatchCreationError(Exception):
|
||||
pass
|
||||
|
||||
def prolog():
|
||||
return textwrap.dedent("""\
|
||||
This script generates patch files for the header files used
|
||||
in the cbmc proof. These patches permit setting values of preprocessor
|
||||
macros as part of the proof configuration.
|
||||
""")
|
||||
|
||||
|
||||
def find_all_defines():
|
||||
"""Collects all define values in Makefile.json.
|
||||
|
||||
Some of the Makefiles use # in the json to make comments.
|
||||
As this is non standard json, we need to remove the comment
|
||||
lines before parsing. Then we extract all defines from the file.
|
||||
"""
|
||||
defines = set()
|
||||
|
||||
proof_dir = os.path.abspath(os.path.join(PATCHES_DIR, "..", "proofs"))
|
||||
|
||||
for fldr, _, fyles in os.walk(proof_dir):
|
||||
if "Makefile.json" in fyles:
|
||||
file = os.path.join(fldr, "Makefile.json")
|
||||
key = "DEF"
|
||||
elif "MakefileCommon.json" in fyles:
|
||||
file = os.path.join(fldr, "MakefileCommon.json")
|
||||
key = "DEF "
|
||||
else:
|
||||
continue
|
||||
with open(file, "r") as source:
|
||||
content = "".join([line for line in source
|
||||
if line and not line.strip().startswith("#")])
|
||||
makefile = json.loads(content)
|
||||
if key in makefile.keys():
|
||||
"""This regex parses the define declaration in Makefile.json
|
||||
'macro(x)=false' is an example for a declaration.
|
||||
'macro' is expected to be matched.
|
||||
"""
|
||||
for define in makefile[key]:
|
||||
matched = DEFINE_REGEX_MAKEFILE.match(define)
|
||||
if matched:
|
||||
defines.add(matched.group(1))
|
||||
return defines
|
||||
|
||||
def manipulate_headerfile(defines, header_file):
|
||||
"""Wraps all defines used in an ifndef."""
|
||||
|
||||
# This regex matches the actual define in the header file.
|
||||
modified_content = ""
|
||||
with open(header_file, "r") as source:
|
||||
last = ""
|
||||
for line in source:
|
||||
match = DEFINE_REGEX_HEADER.match(line)
|
||||
if (match and
|
||||
match.group(1) in defines and
|
||||
not last.lstrip().startswith("#ifndef")):
|
||||
full_def = line
|
||||
# this loop deals with multiline definitions
|
||||
while line.rstrip().endswith("\\"):
|
||||
line = next(source)
|
||||
full_def += line
|
||||
# indentation for multiline definitions can be improved
|
||||
modified_content += textwrap.dedent("""\
|
||||
#ifndef {target}
|
||||
{original}\
|
||||
#endif
|
||||
""".format(target=match.group(1), original=full_def))
|
||||
else:
|
||||
modified_content += line
|
||||
last = line
|
||||
with open(header_file, "w") as output:
|
||||
output.write(modified_content)
|
||||
|
||||
|
||||
def header_dirty(header_files):
|
||||
"""Check that the header_file is not previously modified."""
|
||||
|
||||
# Git does not update the modified file list returned by diff-files on
|
||||
# apply -R (at least not on MacOS).
|
||||
# Running git status updates git's internal state.
|
||||
status = subprocess.run(["git", "status"], stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.PIPE, universal_newlines=True)
|
||||
|
||||
diff_state = subprocess.run(["git", "diff-files"], stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, universal_newlines=True)
|
||||
|
||||
if status.returncode:
|
||||
raise DirtyGitError(textwrap.dedent("""\
|
||||
Could not run git status. Exited: {}
|
||||
stderr: {}
|
||||
""".format(status.returncode, status.stderr)))
|
||||
|
||||
if diff_state.returncode:
|
||||
raise DirtyGitError(textwrap.dedent("""\
|
||||
Could not run git diff-files. Exited: {}
|
||||
stderr: {}
|
||||
""".format(diff_state.returncode, diff_state.stderr)))
|
||||
|
||||
for header_file in header_files:
|
||||
if os.path.basename(header_file) + "\n" in diff_state.stdout:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def create_patch(defines, header_file):
|
||||
"""Computes a patch enclosing defines used in CBMC proofs with #ifndef."""
|
||||
manipulate_headerfile(defines, header_file)
|
||||
patch = subprocess.run(["git", "diff", header_file],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, universal_newlines=True)
|
||||
cleaned = subprocess.run(["git", "checkout", "--", header_file],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.PIPE, universal_newlines=True)
|
||||
|
||||
if patch.returncode:
|
||||
raise PatchCreationError(textwrap.dedent("""\
|
||||
git diff exited with error code: {}
|
||||
stderr: {}
|
||||
""".format(patch.returncode, patch.stderr)))
|
||||
|
||||
if cleaned.returncode:
|
||||
raise DirtyGitError(textwrap.dedent("""\
|
||||
git checkout for cleaning files failed with error code: {}
|
||||
on file {}
|
||||
stderr: {}
|
||||
""".format(cleaned.returncode, header_file, cleaned.stderr)))
|
||||
|
||||
header_path_part = header_file.replace(os.sep, "_")
|
||||
path_name = "auto_patch_" + header_path_part + ".patch"
|
||||
path_name = os.path.join(PATCHES_DIR, path_name)
|
||||
if patch.stdout:
|
||||
with open(path_name, "w") as patch_file:
|
||||
patch_file.write(patch.stdout)
|
||||
|
||||
|
||||
def create_patches(headers):
|
||||
defines = find_all_defines()
|
||||
|
||||
if not header_dirty(headers):
|
||||
for header in headers:
|
||||
create_patch(defines, header)
|
||||
else:
|
||||
raise DirtyGitError(textwrap.dedent("""\
|
||||
It seems like one of the header files is in dirty state.
|
||||
This script cannot patch files in dirty state.
|
||||
"""))
|
||||
|
||||
# Invoke 'python3 -m unittest compute_patch.py" for running tests.
|
||||
class TestDefineRegexes(unittest.TestCase):
|
||||
def test_makefile_regex(self):
|
||||
input1 = "ipconfigETHERNET_MINIMUM_PACKET_BYTES={MINIMUM_PACKET_BYTES}"
|
||||
input2 = "ipconfigETHERNET_MINIMUM_PACKET_BYTES=50"
|
||||
input3 = "'configASSERT(X)=__CPROVER_assert(x, \"must hold\")'"
|
||||
input4 = '"configASSERT (X)=__CPROVER_assert(x, "must hold")"'
|
||||
input5 = "configASSERT(X)=__CPROVER_assert(x,\"must hold\")"
|
||||
|
||||
match1 = DEFINE_REGEX_MAKEFILE.match(input1)
|
||||
match2 = DEFINE_REGEX_MAKEFILE.match(input2)
|
||||
match3 = DEFINE_REGEX_MAKEFILE.match(input3)
|
||||
match4 = DEFINE_REGEX_MAKEFILE.match(input4)
|
||||
match5 = DEFINE_REGEX_MAKEFILE.match(input5)
|
||||
|
||||
self.assertIsNotNone(match1)
|
||||
self.assertIsNotNone(match2)
|
||||
self.assertIsNotNone(match3)
|
||||
self.assertIsNotNone(match4)
|
||||
self.assertIsNotNone(match5)
|
||||
|
||||
self.assertEqual(match1.group(1),
|
||||
"ipconfigETHERNET_MINIMUM_PACKET_BYTES")
|
||||
self.assertEqual(match2.group(1),
|
||||
"ipconfigETHERNET_MINIMUM_PACKET_BYTES")
|
||||
self.assertEqual(match3.group(1), "configASSERT")
|
||||
self.assertEqual(match4.group(1), "configASSERT")
|
||||
self.assertEqual(match5.group(1), "configASSERT")
|
||||
|
||||
|
||||
def test_header_regex(self):
|
||||
input1 = ("#define configASSERT( x ) if( ( x ) == 0 )" +
|
||||
"vAssertCalled( __FILE__, __LINE__ )")
|
||||
input2 = "#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 )"
|
||||
input3 = "#define ipconfigINCLUDE_FULL_INET_ADDR 1"
|
||||
|
||||
match1 = DEFINE_REGEX_HEADER.match(input1)
|
||||
match2 = DEFINE_REGEX_HEADER.match(input2)
|
||||
match3 = DEFINE_REGEX_HEADER.match(input3)
|
||||
|
||||
self.assertIsNotNone(match1)
|
||||
self.assertIsNotNone(match2)
|
||||
self.assertIsNotNone(match3)
|
||||
|
||||
self.assertEqual(match1.group(1), "configASSERT")
|
||||
self.assertEqual(match2.group(1), "ipconfigMAX_ARP_RETRANSMISSIONS")
|
||||
self.assertEqual(match3.group(1), "ipconfigINCLUDE_FULL_INET_ADDR")
|
||||
|
||||
if __name__ == '__main__':
|
||||
create_patches(HEADERS)
|
||||
36
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/patch.py
Executable file
36
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/patch.py
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
from patches_constants import PATCHES_DIR
|
||||
|
||||
def patch():
|
||||
if os.path.isfile("patched"):
|
||||
sys.exit()
|
||||
|
||||
applied_patches = []
|
||||
failed_patches = []
|
||||
for tmpfile in glob(os.path.join(PATCHES_DIR, "*.patch")):
|
||||
print("patch", tmpfile)
|
||||
result = subprocess.run(["git", "apply", "--ignore-space-change", "--ignore-whitespace", tmpfile],
|
||||
cwd=os.path.join("..", "..", "..", ".."))
|
||||
if result.returncode:
|
||||
failed_patches.append(tmpfile)
|
||||
logging.error("patching failed: %s", tmpfile)
|
||||
else:
|
||||
applied_patches.append(tmpfile)
|
||||
|
||||
with open(os.path.join(PATCHES_DIR, "patched"), "w") as outp:
|
||||
print("Success:", file=outp)
|
||||
print("\n".join(map(lambda x: "\t" + x, applied_patches)), file=outp)
|
||||
|
||||
print("Failure:", file=outp)
|
||||
print("\n".join(map(lambda x: "\t" + x, failed_patches)), file=outp)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
patch()
|
||||
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Constants for the generation of patches for CBMC proofs.
|
||||
#
|
||||
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
import os
|
||||
|
||||
PATCHES_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
shared_prefix = [
|
||||
"."
|
||||
]
|
||||
shared_prefix_port = [
|
||||
"..", "..", "FreeRTOS-Kernel", "portable", "MSVC-MingW"
|
||||
]
|
||||
|
||||
absolute_prefix = os.path.abspath(os.path.join(PATCHES_DIR, *shared_prefix))
|
||||
absolute_prefix_port = os.path.abspath(os.path.join(PATCHES_DIR, *shared_prefix_port))
|
||||
|
||||
HEADERS = [os.path.join(absolute_prefix, "FreeRTOSConfig.h"),
|
||||
os.path.join(absolute_prefix, "FreeRTOSIPConfig.h"),
|
||||
os.path.join(absolute_prefix_port, "portmacro.h")]
|
||||
42
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/unpatch.py
Executable file
42
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/patches/unpatch.py
Executable file
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# unpatching changes for the CBMC proofs.
|
||||
#
|
||||
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
from patches_constants import PATCHES_DIR
|
||||
|
||||
try:
|
||||
os.remove(os.path.join(PATCHES_DIR, "patched"))
|
||||
except FileNotFoundError:
|
||||
print("Nothing to do here.")
|
||||
sys.exit(0)
|
||||
for tmpfile in glob(os.path.join(PATCHES_DIR, "*.patch")):
|
||||
print("unpatch", tmpfile)
|
||||
result = subprocess.run(["git", "apply", "-R", "--ignore-space-change", "--ignore-whitespace", tmpfile],
|
||||
cwd=os.path.join("..", "..", "..", ".."))
|
||||
if result.returncode:
|
||||
print("Unpatching failed: {}".format(tmpfile))
|
||||
10
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/proofs/.gitignore
vendored
Normal file
10
kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/cbmc/proofs/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# These files are generated by make_type_header_files.py
|
||||
*_datastructure.h
|
||||
|
||||
Makefile
|
||||
Makefile.common
|
||||
cbmc-batch.yaml
|
||||
**/*.txt
|
||||
**/*.goto
|
||||
|
||||
!CMakeLists.txt
|
||||
@ -0,0 +1,29 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "list.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
/*We assume that the pxGetNetworkBufferWithDescriptor function is implemented correctly and returns a valid data structure. */
|
||||
/*This is the mock to mimic the correct expected behavior. If this allocation fails, this might invalidate the proof. */
|
||||
NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes,
|
||||
TickType_t xBlockTimeTicks )
|
||||
{
|
||||
NetworkBufferDescriptor_t * pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) malloc( sizeof( NetworkBufferDescriptor_t ) );
|
||||
|
||||
__CPROVER_assume( pxNetworkBuffer != NULL );
|
||||
|
||||
pxNetworkBuffer->pucEthernetBuffer = malloc( xRequestedSizeBytes );
|
||||
__CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL );
|
||||
|
||||
pxNetworkBuffer->xDataLength = xRequestedSizeBytes;
|
||||
return pxNetworkBuffer;
|
||||
}
|
||||
|
||||
void harness()
|
||||
{
|
||||
vARPAgeCache();
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
{
|
||||
"ENTRY": "ARPAgeCache",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--unwindset vARPAgeCache.0:7",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
Assuming that xNetworkInterfaceOutput is memory safe,
|
||||
this harness proves the memory safety of the vARPAgeCache function.
|
||||
@ -0,0 +1,32 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
void harness()
|
||||
{
|
||||
/*
|
||||
* The assumption made here is that the buffer pointed by pucEthernetBuffer
|
||||
* is at least allocated to sizeof(ARPPacket_t) size but eventually a even larger buffer.
|
||||
* This is not checked inside vARPGenerateRequestPacket.
|
||||
*/
|
||||
uint8_t ucBUFFER_SIZE;
|
||||
|
||||
__CPROVER_assume( ucBUFFER_SIZE >= sizeof( ARPPacket_t ) && ucBUFFER_SIZE < 2 * sizeof( ARPPacket_t ) );
|
||||
void * xBuffer = malloc( ucBUFFER_SIZE );
|
||||
|
||||
__CPROVER_assume( xBuffer != NULL );
|
||||
|
||||
NetworkBufferDescriptor_t xNetworkBuffer2;
|
||||
|
||||
xNetworkBuffer2.pucEthernetBuffer = xBuffer;
|
||||
xNetworkBuffer2.xDataLength = ucBUFFER_SIZE;
|
||||
|
||||
/* vARPGenerateRequestPacket asserts buffer has room for a packet */
|
||||
__CPROVER_assume( xNetworkBuffer2.xDataLength >= sizeof( ARPPacket_t ) );
|
||||
vARPGenerateRequestPacket( &xNetworkBuffer2 );
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"ENTRY": "ARPGenerateRequestPacket",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
Given that the pointer target of xNetworkDescriptor.pucEthernetBuffer is allocated
|
||||
to the size claimed in xNetworkDescriptor.xDataLength,
|
||||
this harness proves the memory safety of ARPGenerateRequestPacket.
|
||||
@ -0,0 +1,17 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
|
||||
void harness()
|
||||
{
|
||||
uint32_t ulIPAddress;
|
||||
MACAddress_t xMACAddress;
|
||||
|
||||
eARPGetCacheEntry( &ulIPAddress, &xMACAddress );
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
{
|
||||
"ENTRY": "ARPGetCacheEntry",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--unwindset prvCacheLookup.0:7",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
{
|
||||
"ARPGetCacheEntry_default":[
|
||||
"ipconfigARP_STORES_REMOTE_ADDRESSES=0",
|
||||
"ipconfigUSE_LLMNR=0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ARPGetCacheEntry_LLMNR": [
|
||||
"ipconfigARP_STORES_REMOTE_ADDRESSES=0",
|
||||
"ipconfigUSE_LLMNR=1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ARPGetCacheEntry_STORE_REMOTE": [
|
||||
"ipconfigARP_STORES_REMOTE_ADDRESSES=1",
|
||||
"ipconfigUSE_LLMNR=0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ARPGetCacheEntry_REMOTE_LLMNR": [
|
||||
"ipconfigARP_STORES_REMOTE_ADDRESSES=1",
|
||||
"ipconfigUSE_LLMNR=1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
The combined proofs in the subdirectories prove that ARPGetCacheEntry
|
||||
is memory safe for all possible combinations of ipconfigARP_STORES_REMOTE_ADDRESSES
|
||||
and ipconfigUSE_LLMNR. These are the only configuration
|
||||
parameters used inside the ARPGetCacheEntry.
|
||||
@ -0,0 +1,16 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
void harness()
|
||||
{
|
||||
MACAddress_t xMACAddress;
|
||||
uint32_t ulIPAddress;
|
||||
|
||||
eARPGetCacheEntryByMac( &xMACAddress, &ulIPAddress );
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"ENTRY": "ARPGetCacheEntryByMac",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 7",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
"ipconfigUSE_ARP_REVERSED_LOOKUP=1", "ipconfigARP_CACHE_ENTRIES=6"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
ARPGetCacheEntryByMac is memory safe,
|
||||
if it is enabled.
|
||||
|
||||
ARPGetCacheEntryByMac does not use multiple configurations internally.
|
||||
@ -0,0 +1,51 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
/* This pointer is maintained by the IP-task. Defined in FreeRTOS_IP.c */
|
||||
extern NetworkBufferDescriptor_t * pxARPWaitingNetworkBuffer;
|
||||
|
||||
/* This is an output function and need not be tested with this proof. */
|
||||
void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress )
|
||||
{
|
||||
}
|
||||
|
||||
void harness()
|
||||
{
|
||||
ARPPacket_t xARPFrame;
|
||||
NetworkBufferDescriptor_t xLocalBuffer;
|
||||
uint16_t usEthernetBufferSize;
|
||||
|
||||
/* Non deterministically determine whether the pxARPWaitingNetworkBuffer will
|
||||
* point to some valid data or will it be NULL. */
|
||||
if( nondet_bool() )
|
||||
{
|
||||
/* The packet must at least be as big as an IP Packet. The size is not
|
||||
* checked in the function as the pointer is stored by the IP-task itself
|
||||
* and therefore it will always be of the required size. */
|
||||
__CPROVER_assume( usEthernetBufferSize >= sizeof( IPPacket_t ) );
|
||||
|
||||
/* Add matching data length to the network buffer descriptor. */
|
||||
__CPROVER_assume( xLocalBuffer.xDataLength == usEthernetBufferSize );
|
||||
|
||||
xLocalBuffer.pucEthernetBuffer = malloc( usEthernetBufferSize );
|
||||
|
||||
/* Since this pointer is maintained by the IP-task, either the pointer
|
||||
* pxARPWaitingNetworkBuffer will be NULL or xLocalBuffer.pucEthernetBuffer
|
||||
* will be non-NULL. */
|
||||
__CPROVER_assume( xLocalBuffer.pucEthernetBuffer != NULL );
|
||||
|
||||
pxARPWaitingNetworkBuffer = &xLocalBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
pxARPWaitingNetworkBuffer = NULL;
|
||||
}
|
||||
|
||||
eARPProcessPacket( &xARPFrame );
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"ENTRY": "ARPProcessPacket",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--unwindset vARPRefreshCacheEntry.0:7,memcmp.0:17,xIsIPInARPCache.0:7",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
The proofs in the subdirectories show that
|
||||
ARPProcessPacket is memory safe independent
|
||||
of the configuration value of
|
||||
ipconfigARP_USE_CLASH_DETECTION.
|
||||
@ -0,0 +1,16 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
void harness()
|
||||
{
|
||||
MACAddress_t xMACAddress;
|
||||
uint32_t ulIPAddress;
|
||||
|
||||
vARPRefreshCacheEntry( &xMACAddress, ulIPAddress );
|
||||
vARPRefreshCacheEntry( NULL, ulIPAddress );
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
{
|
||||
"ENTRY": "ARPRefreshCacheEntry",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--unwindset vARPRefreshCacheEntry.0:7,memcmp.0:17",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
{"NOT_STORE_REMOTE":["ipconfigARP_STORES_REMOTE_ADDRESSES=0"]},
|
||||
{"STORE_REMOTE":["ipconfigARP_STORES_REMOTE_ADDRESSES=1"]}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
The proofs in this directory guarantee together that
|
||||
ARPRefreshCacheEntry is memory safe independent
|
||||
of the configuration value of
|
||||
ipconfigARP_STORES_REMOTE_ADDRESSES.
|
||||
@ -0,0 +1,13 @@
|
||||
/* / * FreeRTOS includes. * / */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
|
||||
void harness()
|
||||
{
|
||||
vARPSendGratuitous();
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
{
|
||||
"ENTRY": "ARPSendGratuitous",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
Abstracting xQueueGenericSend away
|
||||
and including tasks.c and FreeRTOS_IP.c:
|
||||
The ARPSendGratutious function is memory safe,
|
||||
if xQueueGenericSend is memory safe.
|
||||
|
||||
queue.c is not compiled into the proof binary.
|
||||
@ -0,0 +1,12 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
void harness()
|
||||
{
|
||||
FreeRTOS_ClearARP();
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"ENTRY": "ClearARP",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
This proof demonstrates the memory safety of the ClearARP function in the FreeRTOS_ARP.c file.
|
||||
No restrictions are made.
|
||||
@ -0,0 +1,58 @@
|
||||
#
|
||||
# FreeRTOS memory safety proofs with CBMC.
|
||||
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation
|
||||
# files (the "Software"), to deal in the Software without
|
||||
# restriction, including without limitation the rights to use, copy,
|
||||
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
# of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://aws.amazon.com/freertos
|
||||
# http://www.FreeRTOS.org
|
||||
#
|
||||
|
||||
{
|
||||
"ENTRY": "OutputARPRequest",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 20"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
#That is the minimal required size for an ARPPacket_t plus offset in the buffer.
|
||||
"MINIMUM_PACKET_BYTES": 50,
|
||||
"DEF":
|
||||
[
|
||||
{
|
||||
"CBMC_PROOF_ASSUMPTION_HOLDS_Packet_bytes": [
|
||||
"CBMC_PROOF_ASSUMPTION_HOLDS=1",
|
||||
"ipconfigETHERNET_MINIMUM_PACKET_BYTES={MINIMUM_PACKET_BYTES}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"CBMC_PROOF_ASSUMPTION_HOLDS_no_packet_bytes": ["CBMC_PROOF_ASSUMPTION_HOLDS=1"]
|
||||
},
|
||||
{
|
||||
"CBMC_PROOF_ASSUMPTION_DOES_NOT_HOLD": ["CBMC_PROOF_ASSUMPTION_HOLDS=0"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* FreeRTOS memory safety proofs with CBMC.
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
|
||||
ARPPacket_t xARPPacket;
|
||||
NetworkBufferDescriptor_t xNetworkBuffer;
|
||||
|
||||
/* STUB!
|
||||
* We assume that the pxGetNetworkBufferWithDescriptor function is
|
||||
* implemented correctly and returns a valid data structure.
|
||||
* This is the mock to mimic the expected behavior.
|
||||
* If this allocation fails, this might invalidate the proof.
|
||||
* FreeRTOS_OutputARPRequest calls pxGetNetworkBufferWithDescriptor
|
||||
* to get a NetworkBufferDescriptor. Then it calls vARPGenerateRequestPacket
|
||||
* passing this buffer along in the function call. vARPGenerateRequestPacket
|
||||
* casts the pointer xNetworkBuffer.pucEthernetBuffer into an ARPPacket_t pointer
|
||||
* and writes a complete ARPPacket to it. Therefore the buffer has to be at least of the size
|
||||
* of an ARPPacket to guarantee memory safety.
|
||||
*/
|
||||
NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes,
|
||||
TickType_t xBlockTimeTicks )
|
||||
{
|
||||
#ifdef CBMC_PROOF_ASSUMPTION_HOLDS
|
||||
#if ( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 )
|
||||
xNetworkBuffer.pucEthernetBuffer = malloc( ipconfigETHERNET_MINIMUM_PACKET_BYTES );
|
||||
#else
|
||||
xNetworkBuffer.pucEthernetBuffer = malloc( xRequestedSizeBytes );
|
||||
#endif
|
||||
#else
|
||||
uint32_t malloc_size;
|
||||
__CPROVER_assert( !__CPROVER_overflow_mult( 2, xRequestedSizeBytes ) );
|
||||
__CPROVER_assume( malloc_size > 0 && malloc_size < 2 * xRequestedSizeBytes );
|
||||
xNetworkBuffer.pucEthernetBuffer = malloc( malloc_size );
|
||||
#endif
|
||||
__CPROVER_assume( xNetworkBuffer.pucEthernetBuffer != NULL );
|
||||
|
||||
xNetworkBuffer.xDataLength = xRequestedSizeBytes;
|
||||
return &xNetworkBuffer;
|
||||
}
|
||||
|
||||
|
||||
void harness()
|
||||
{
|
||||
uint32_t ulIPAddress;
|
||||
|
||||
FreeRTOS_OutputARPRequest( ulIPAddress );
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
This is the memory safety proof for FreeRTOS_OutputARPRequest.
|
||||
|
||||
This proof is a work-in-progress. Proof assumptions are described in
|
||||
the harness. The proof also assumes the following functions are
|
||||
memory safe and have no side effects relevant to the memory safety of
|
||||
this function:
|
||||
|
||||
* xNetworkInterfaceOutput
|
||||
|
||||
This proof checks FreeRTOS_OutputARPRequest in multiple configuration:
|
||||
|
||||
* The config_CBMC_PROOF_ASSUMPTION_HOLDS_no_packet_bytes proof
|
||||
guarantees that for a buffer allocated to xDataLength,
|
||||
the code executed by the FreeRTOS_OutputARPRequest function
|
||||
call of FreeRTOS_ARP.c is memory safe.
|
||||
* If the ipconfigETHERNET_MINIMUM_PACKET_BYTES is set and the
|
||||
buffer allocated by pxGetNetworkBufferWithDescriptor allocates
|
||||
a buffer of at least ipconfigETHERNET_MINIMUM_PACKET_BYTES,
|
||||
the config_CBMC_PROOF_ASSUMPTION_HOLDS_Packet_bytes proof
|
||||
guarantees that the code executed by the
|
||||
FreeRTOS_OutputARPRequest function call
|
||||
of FreeRTOS_ARP.c is memory safe.
|
||||
* The third configuration in the subdirectory
|
||||
config_CBMC_PROOF_ASSUMPTION_DOES_NOT_HOLD demonstrates
|
||||
that the code is not memory safe, if the allocation
|
||||
code violates our assumption.
|
||||
* All proofs mock the pxGetNetworkBufferWithDescriptor
|
||||
function for modelling the assumptions about the
|
||||
buffer management layer.
|
||||
@ -0,0 +1,14 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOSIPConfig.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
void harness()
|
||||
{
|
||||
FreeRTOS_PrintARPCache();
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"ENTRY": "FreeRTOS_PrintARPCache",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 7",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
"ipconfigARP_CACHE_ENTRIES=6"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
FreeRTOS_PrintARPCache_harness.c is memory safe,
|
||||
assuming vLoggingPrintf is correct and memory safe.
|
||||
|
||||
FreeRTOS_PrintARPCache does not use multiple configurations.
|
||||
@ -0,0 +1,48 @@
|
||||
{
|
||||
"ENTRY": "OutputARPRequest",
|
||||
"MINIMUM_PACKET_BYTES": 50,
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind {MINIMUM_PACKET_BYTES}",
|
||||
"--unwindset xNetworkBuffersInitialise.0:3,xNetworkBuffersInitialise.1:3,vListInsert.0:3,pxGetNetworkBufferWithDescriptor.0:3,pxGetNetworkBufferWithDescriptor.1:3,vNetworkInterfaceAllocateRAMToBuffers.0:3"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/portable/BufferManagement/BufferAllocation_1.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/queue.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
{
|
||||
"minimal_configuration":
|
||||
[
|
||||
"ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS=2",
|
||||
"configUSE_TRACE_FACILITY=0",
|
||||
"configGENERATE_RUN_TIME_STATS=0",
|
||||
"ipconfigUSE_LINKED_RX_MESSAGES=0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"minimal_configuration_minimal_packet_size":
|
||||
[
|
||||
"ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS=2",
|
||||
"configUSE_TRACE_FACILITY=0",
|
||||
"configGENERATE_RUN_TIME_STATS=0",
|
||||
"ipconfigETHERNET_MINIMUM_PACKET_BYTES={MINIMUM_PACKET_BYTES}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"minimal_configuration_linked_rx_messages":
|
||||
[
|
||||
"ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS=2",
|
||||
"configUSE_TRACE_FACILITY=0",
|
||||
"configGENERATE_RUN_TIME_STATS=0",
|
||||
"ipconfigUSE_LINKED_RX_MESSAGES=1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
/* This harness is linked against
|
||||
* libraries/freertos_plus/standard/freertos_plus_tcp/source/portable/BufferManagement/BufferAllocation_1.goto
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#if ( ipconfigUSE_LLMNR == 1 )
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#endif /* ipconfigUSE_LLMNR */
|
||||
#include "NetworkInterface.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
|
||||
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
|
||||
{
|
||||
for( int x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
|
||||
{
|
||||
NetworkBufferDescriptor_t * current = &pxNetworkBuffers[ x ];
|
||||
#if ( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 )
|
||||
current->pucEthernetBuffer = malloc( sizeof( ARPPacket_t ) + ( ipconfigETHERNET_MINIMUM_PACKET_BYTES - sizeof( ARPPacket_t ) ) );
|
||||
#else
|
||||
current->pucEthernetBuffer = malloc( sizeof( ARPPacket_t ) );
|
||||
#endif
|
||||
__CPROVER_assume( current->pucEthernetBuffer != NULL );
|
||||
current->xDataLength = sizeof( ARPPacket_t );
|
||||
}
|
||||
}
|
||||
|
||||
/* The code expects that the Semaphore creation relying on pvPortMalloc
|
||||
* is successful. This is checked by an assert statement, that gets
|
||||
* triggered when the allocation fails. Nevertheless, the code is perfectly
|
||||
* guarded against a failing Semaphore allocation. To make the assert pass,
|
||||
* it is assumed for now, that pvPortMalloc doesn't fail. Using a model allowing
|
||||
* failures of the allocation might be possible
|
||||
* after removing the assert in l.105 of BufferAllocation_1.c, from a memory
|
||||
* safety point of view. */
|
||||
void * pvPortMalloc( size_t xWantedSize )
|
||||
{
|
||||
void * ptr = malloc( xWantedSize );
|
||||
|
||||
__CPROVER_assume( ptr != NULL );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is implemented by a third party.
|
||||
* After looking through a couple of samples in the demos folder, it seems
|
||||
* like the only shared contract is that you want to add the if statement
|
||||
* for releasing the buffer to the end. Apart from that, it is up to the vendor,
|
||||
* how to write this code out to the network.
|
||||
*/
|
||||
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
|
||||
BaseType_t bReleaseAfterSend )
|
||||
{
|
||||
if( bReleaseAfterSend != pdFALSE )
|
||||
{
|
||||
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||
}
|
||||
}
|
||||
|
||||
void harness()
|
||||
{
|
||||
BaseType_t xRes = xNetworkBuffersInitialise();
|
||||
|
||||
if( xRes == pdPASS )
|
||||
{
|
||||
uint32_t ulIPAddress;
|
||||
FreeRTOS_OutputARPRequest( ulIPAddress );
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
This is the memory safety proof for ```FreeRTOS_OutputARPRequest```
|
||||
method combined with the BufferAllocation_1.c allocation strategy.
|
||||
|
||||
This proof is a work-in-progress. Proof assumptions are described in
|
||||
the harness. The proof also assumes the following functions are
|
||||
memory safe and have no side effects relevant to the memory safety of
|
||||
this function:
|
||||
|
||||
* vPortEnterCritical
|
||||
* vPortExitCritical
|
||||
* vPortGenerateSimulatedInterrupt
|
||||
* vAssertCalled
|
||||
* xTaskGetSchedulerState
|
||||
* pvTaskIncrementMutexHeldCount
|
||||
* xTaskRemoveFromEventList
|
||||
* xTaskPriorityDisinherit
|
||||
|
||||
This proof checks ```FreeRTOS_OutputARPRequest``` in multiple configurations.
|
||||
All assume the memory safety of vNetworkInterfaceAllocateRAMToBuffers.
|
||||
* The ```config_minimal_configuration``` proof sets
|
||||
```ipconfigUSE_LINKED_RX_MESSAGES=0```.
|
||||
* The ```config_minimal_configuration_linked_rx_messages``` proof sets
|
||||
```ipconfigUSE_LINKED_RX_MESSAGES=1```.
|
||||
* The ```minimal_configuration_minimal_packet_size``` proof sets
|
||||
```ipconfigETHERNET_MINIMUM_PACKET_BYTES``` to 50.
|
||||
|
||||
All harnesses include the queue.c file, but test only for the happy path.
|
||||
@ -0,0 +1,49 @@
|
||||
{
|
||||
"ENTRY": "OutputARPRequest",
|
||||
"MINIMUM_PACKET_BYTES": 50,
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind {MINIMUM_PACKET_BYTES}",
|
||||
"--unwindset xNetworkBuffersInitialise.0:3,xNetworkBuffersInitialise.1:3,vListInsert.0:3,pxGetNetworkBufferWithDescriptor.0:3,pxGetNetworkBufferWithDescriptor.1:3,vNetworkInterfaceAllocateRAMToBuffers.0:3"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/portable/BufferManagement/BufferAllocation_2.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/queue.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
{
|
||||
"minimal_configuration":
|
||||
[
|
||||
"ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS=2",
|
||||
"configUSE_TRACE_FACILITY=0",
|
||||
"configGENERATE_RUN_TIME_STATS=0",
|
||||
"ipconfigUSE_LINKED_RX_MESSAGES=0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"minimal_configuration_minimal_packet_size":
|
||||
[
|
||||
"ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS=2",
|
||||
"configUSE_TRACE_FACILITY=0",
|
||||
"configGENERATE_RUN_TIME_STATS=0",
|
||||
"ipconfigETHERNET_MINIMUM_PACKET_BYTES={MINIMUM_PACKET_BYTES}",
|
||||
"ipconfigUSE_TCP=1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"minimal_configuration_linked_rx_messages":
|
||||
[
|
||||
"ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS=2",
|
||||
"configUSE_TRACE_FACILITY=0",
|
||||
"configGENERATE_RUN_TIME_STATS=0",
|
||||
"ipconfigUSE_LINKED_RX_MESSAGES=1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/* This harness is linked against
|
||||
* libraries/freertos_plus/standard/freertos_plus_tcp/source/portable/BufferManagement/BufferAllocation_2.goto
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#if ( ipconfigUSE_LLMNR == 1 )
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#endif /* ipconfigUSE_LLMNR */
|
||||
#include "NetworkInterface.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
|
||||
void * pvPortMalloc( size_t xWantedSize )
|
||||
{
|
||||
void * ptr = malloc( xWantedSize );
|
||||
|
||||
__CPROVER_assume( ptr != NULL );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void vPortFree( void * pv )
|
||||
{
|
||||
free( pv );
|
||||
}
|
||||
|
||||
/*
|
||||
* This function function writes a buffer to the network. We stub it
|
||||
* out here, and assume it has no side effects relevant to memory safety.
|
||||
*/
|
||||
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
|
||||
BaseType_t bReleaseAfterSend )
|
||||
{
|
||||
if( bReleaseAfterSend != pdFALSE )
|
||||
{
|
||||
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||
}
|
||||
}
|
||||
|
||||
void harness()
|
||||
{
|
||||
BaseType_t xRes = xNetworkBuffersInitialise();
|
||||
|
||||
if( xRes == pdPASS )
|
||||
{
|
||||
uint32_t ulIPAddress;
|
||||
FreeRTOS_OutputARPRequest( ulIPAddress );
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
This is the memory safety proof for FreeRTOS_OutputARPRequest
|
||||
method combined with the BufferAllocation_2.c allocation strategy.
|
||||
|
||||
This proof is a work-in-progress. Proof assumptions are described in
|
||||
the harness. The proof also assumes the following functions are
|
||||
memory safe and have no side effects relevant to the memory safety of
|
||||
this function:
|
||||
|
||||
* vPortEnterCritical
|
||||
* vPortExitCritical
|
||||
* vPortGenerateSimulatedInterrupt
|
||||
* vAssertCalled
|
||||
* xTaskGetSchedulerState
|
||||
* pvTaskIncrementMutexHeldCount
|
||||
* xTaskRemoveFromEventList
|
||||
* xTaskPriorityDisinherit
|
||||
|
||||
* pvPortMalloc
|
||||
* pvPortFree
|
||||
* xNetworkInterfaceOutput
|
||||
* vNetworkInterfaceAllocateRAMToBuffers
|
||||
|
||||
This proof disables the tracing library in the header.
|
||||
|
||||
This proof checks FreeRTOS_OutputARPRequest in multiple configuration:
|
||||
|
||||
* The proof in the directory config_minimal_configuration guarantees
|
||||
that the implementation and interaction between
|
||||
FreeRTOS_OutputARPRequest and
|
||||
FreeRTOS-Plus-TCP/source/portable/BufferManagement/BufferAllocation_2.c
|
||||
are memory save. This proof depends entirely of the implementation
|
||||
correctness of vNetworkInterfaceAllocateRAMToBuffers.
|
||||
* The proof in directory minimal_configuration_minimal_packet_size
|
||||
guarantees that using
|
||||
FreeRTOS-Plus-TCP/source/portable/BufferManagement/BufferAllocation_2.c
|
||||
along with the ipconfigETHERNET_MINIMUM_PACKET_BYTES is memory save
|
||||
as long as TCP is enabled ( ipconfigUSE_TCP 1 ) and
|
||||
ipconfigETHERNET_MINIMUM_PACKET_BYTES < sizeof( TCPPacket_t ).
|
||||
* The directory minimal_configuration_minimal_packet_size_no_tcp
|
||||
reminds that ipconfigETHERNET_MINIMUM_PACKET_BYTES must not be used
|
||||
if TCP is disabled ( ipconfigUSE_TCP 1 ) along with the
|
||||
FreeRTOS-Plus-TCP/source/portable/BufferManagement/BufferAllocation_2.c
|
||||
allocator.
|
||||
* The proof in directory
|
||||
config_minimal_configuration_linked_rx_messages guarantees that the
|
||||
ipconfigUSE_LINKED_RX_MESSAGES define does not interfere with the
|
||||
memory safety claim.
|
||||
|
||||
All harnesses include the queue.c file, but test only for the happy path.
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"ENTRY": "ulARPRemoveCacheEntryByMac",
|
||||
"NUMBER_OF_CACHE_ENTRIES":6,
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
"INSTFLAGS":
|
||||
[
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
"ipconfigUSE_ARP_REMOVE_ENTRY=1",
|
||||
"ipconfigARP_CACHE_ENTRIES={NUMBER_OF_CACHE_ENTRIES}"
|
||||
],
|
||||
"INC":
|
||||
[
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/include"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
|
||||
void harness()
|
||||
{
|
||||
const MACAddress_t xMACAddress;
|
||||
|
||||
/* The pointer passed to ulARPRemoveCacheEntryByMac cannot be NULL
|
||||
* (see the API definition). */
|
||||
ulARPRemoveCacheEntryByMac( &xMACAddress );
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "tasksStubs.h"
|
||||
|
||||
#ifndef TASK_STUB_COUNTER
|
||||
#define TASK_STUB_COUNTER 0;
|
||||
#endif
|
||||
|
||||
/* 5 is a magic number, but we need some number here as a default value.
|
||||
* This value is used to bound any loop depending on xTaskCheckForTimeOut
|
||||
* as a loop bound. It should be overwritten in the Makefile.json adapting
|
||||
* to the performance requirements of the harness. */
|
||||
#ifndef TASK_STUB_COUNTER_LIMIT
|
||||
#define TASK_STUB_COUNTER_LIMIT 5;
|
||||
#endif
|
||||
|
||||
|
||||
static BaseType_t xCounter = TASK_STUB_COUNTER;
|
||||
static BaseType_t xCounterLimit = TASK_STUB_COUNTER_LIMIT;
|
||||
|
||||
BaseType_t xTaskGetSchedulerState( void )
|
||||
{
|
||||
return xState;
|
||||
}
|
||||
|
||||
|
||||
/* This function is another method apart from overwriting the defines to init the max
|
||||
* loop bound. */
|
||||
void vInitTaskCheckForTimeOut( BaseType_t maxCounter,
|
||||
BaseType_t maxCounter_limit )
|
||||
{
|
||||
xCounter = maxCounter;
|
||||
xCounterLimit = maxCounter_limit;
|
||||
}
|
||||
|
||||
/* This is mostly called in a loop. For CBMC, we have to bound the loop
|
||||
* to a max limits of calls. Therefore this Stub models a nondet timeout in
|
||||
* max TASK_STUB_COUNTER_LIMIT iterations.*/
|
||||
BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
||||
TickType_t * const pxTicksToWait )
|
||||
{
|
||||
++xCounter;
|
||||
|
||||
if( xCounter == xCounterLimit )
|
||||
{
|
||||
return pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nondet_basetype();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
list(APPEND cbmc_compile_options
|
||||
-m32
|
||||
)
|
||||
|
||||
list(APPEND cbmc_compile_definitions
|
||||
CBMC
|
||||
WINVER=0x400
|
||||
_CONSOLE
|
||||
_CRT_SECURE_NO_WARNINGS
|
||||
_DEBUG
|
||||
_WIN32_WINNT=0x0500
|
||||
__PRETTY_FUNCTION__=__FUNCTION__
|
||||
__free_rtos__
|
||||
)
|
||||
|
||||
list(APPEND cbmc_compile_includes
|
||||
${CMAKE_SOURCE_DIR}/Source/include
|
||||
${CMAKE_SOURCE_DIR}/Source/portable/MSVC-MingW
|
||||
${CMAKE_SOURCE_DIR}/Source/../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement
|
||||
${CMAKE_SOURCE_DIR}/Source/../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include
|
||||
${CMAKE_SOURCE_DIR}/Source/../../FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC
|
||||
${cbmc_dir}/include
|
||||
${cbmc_dir}/windows
|
||||
)
|
||||
|
||||
# Remove --flag for a specific proof with list(REMOVE_ITEM cbmc_flags --flag)
|
||||
list(APPEND cbmc_flags
|
||||
--32
|
||||
--bounds-check
|
||||
--pointer-check
|
||||
--div-by-zero-check
|
||||
--float-overflow-check
|
||||
--nan-check
|
||||
--nondet-static
|
||||
--pointer-overflow-check
|
||||
--signed-overflow-check
|
||||
--undefined-shift-check
|
||||
--unsigned-overflow-check
|
||||
)
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
#include "cbmc.h"
|
||||
|
||||
/****************************************************************
|
||||
* Signature of function under test
|
||||
****************************************************************/
|
||||
|
||||
BaseType_t __CPROVER_file_local_FreeRTOS_TCP_IP_c_prvCheckOptions( FreeRTOS_Socket_t * pxSocket,
|
||||
const NetworkBufferDescriptor_t * pxNetworkBuffer );
|
||||
|
||||
/****************************************************************
|
||||
* Declare the buffer size external to the harness so it can be
|
||||
* accessed by the preconditions of prvSingleStepTCPHeaderOptions, and
|
||||
* give the buffer size an unconstrained value in the harness itself.
|
||||
****************************************************************/
|
||||
size_t buffer_size;
|
||||
|
||||
/****************************************************************
|
||||
* Function contract proved correct by CheckOptionsOuter
|
||||
****************************************************************/
|
||||
|
||||
int32_t __CPROVER_file_local_FreeRTOS_TCP_IP_c_prvSingleStepTCPHeaderOptions( const uint8_t * const pucPtr,
|
||||
size_t uxTotalLength,
|
||||
FreeRTOS_Socket_t * const pxSocket,
|
||||
BaseType_t xHasSYNFlag )
|
||||
{
|
||||
/* CBMC model of pointers limits the size of the buffer */
|
||||
|
||||
/* Preconditions */
|
||||
__CPROVER_assert( buffer_size < CBMC_MAX_OBJECT_SIZE,
|
||||
"prvSingleStepTCPHeaderOptions: buffer_size < CBMC_MAX_OBJECT_SIZE" );
|
||||
__CPROVER_assert( 8 <= buffer_size,
|
||||
"prvSingleStepTCPHeaderOptions: 8 <= buffer_size" );
|
||||
__CPROVER_assert( pucPtr != NULL,
|
||||
"prvSingleStepTCPHeaderOptions: pucPtr != NULL" );
|
||||
__CPROVER_assert( uxTotalLength <= buffer_size,
|
||||
"prvSingleStepTCPHeaderOptions: uxTotalLength <= buffer_size" );
|
||||
__CPROVER_assert( pxSocket != NULL,
|
||||
"prvSingleStepTCPHeaderOptions: pxSocket != NULL" );
|
||||
|
||||
/* Postconditions */
|
||||
int32_t index;
|
||||
|
||||
__CPROVER_assume( ( index == -1 ) || ( index == 1 ) || ( index <= uxTotalLength ) );
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Proof of CheckOptions
|
||||
****************************************************************/
|
||||
|
||||
void harness()
|
||||
{
|
||||
/* Give buffer_size an unconstrained value */
|
||||
size_t buf_size;
|
||||
|
||||
buffer_size = buf_size;
|
||||
|
||||
/* pxSocket can be any socket */
|
||||
FreeRTOS_Socket_t pxSocket;
|
||||
|
||||
/* pxNetworkBuffer can be any buffer descriptor with any buffer */
|
||||
NetworkBufferDescriptor_t pxNetworkBuffer;
|
||||
|
||||
pxNetworkBuffer.pucEthernetBuffer = malloc( buffer_size );
|
||||
__CPROVER_assume( pxNetworkBuffer.pucEthernetBuffer != NULL );
|
||||
pxNetworkBuffer.xDataLength = buffer_size;
|
||||
|
||||
/****************************************************************
|
||||
* Specification and proof of CheckOptions
|
||||
****************************************************************/
|
||||
|
||||
/* CBMC model of pointers limits the size of the buffer */
|
||||
__CPROVER_assume( buffer_size < CBMC_MAX_OBJECT_SIZE );
|
||||
|
||||
/* Bound required to bound iteration over the buffer */
|
||||
__CPROVER_assume( buffer_size <= BUFFER_SIZE );
|
||||
|
||||
/* Buffer must be big enough to hold pxTCPPacket and pxTCPHeader */
|
||||
__CPROVER_assume( buffer_size > 47 );
|
||||
|
||||
__CPROVER_file_local_FreeRTOS_TCP_IP_c_prvCheckOptions( &pxSocket, &pxNetworkBuffer );
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
{
|
||||
"ENTRY": "CheckOptions",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
" --unwindset __CPROVER_file_local_FreeRTOS_TCP_IP_c_prvCheckOptions.0:41"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_WIN.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Stream_Buffer.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto"
|
||||
],
|
||||
"BUFFER_SIZE": 100,
|
||||
"DEF":
|
||||
[
|
||||
"BUFFER_SIZE={BUFFER_SIZE}"
|
||||
],
|
||||
"OPT":
|
||||
[
|
||||
"--export-file-local-symbols"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
#include "cbmc.h"
|
||||
|
||||
/****************************************************************
|
||||
* Signature of function under test
|
||||
****************************************************************/
|
||||
|
||||
void prvReadSackOption( const uint8_t * const pucPtr,
|
||||
size_t uxIndex,
|
||||
FreeRTOS_Socket_t * const pxSocket );
|
||||
|
||||
/****************************************************************
|
||||
* Proof of prvReadSackOption function contract
|
||||
****************************************************************/
|
||||
|
||||
|
||||
|
||||
void harness()
|
||||
{
|
||||
/* pucPtr points into a buffer */
|
||||
size_t buffer_size;
|
||||
uint8_t * pucPtr = malloc( buffer_size );
|
||||
|
||||
__CPROVER_assume( pucPtr != NULL );
|
||||
|
||||
/* uxIndex in an index into the buffer */
|
||||
size_t uxIndex;
|
||||
|
||||
/* pxSocket can be any socket with some initialized values */
|
||||
FreeRTOS_Socket_t * pxSocket = malloc( sizeof( FreeRTOS_Socket_t ) );
|
||||
|
||||
__CPROVER_assume( pxSocket != NULL );
|
||||
|
||||
pxSocket->u.xTCP.txStream = malloc( sizeof( StreamBuffer_t ) );
|
||||
__CPROVER_assume( pxSocket->u.xTCP.txStream != NULL );
|
||||
|
||||
vListInitialise( &pxSocket->u.xTCP.xTCPWindow.xWaitQueue );
|
||||
|
||||
if( nondet_bool() )
|
||||
{
|
||||
TCPSegment_t * segment = malloc( sizeof( TCPSegment_t ) );
|
||||
__CPROVER_assume( segment != NULL );
|
||||
listSET_LIST_ITEM_OWNER( &segment->xQueueItem, ( void * ) segment );
|
||||
vListInsertEnd( &pxSocket->u.xTCP.xTCPWindow.xWaitQueue, &segment->xQueueItem );
|
||||
}
|
||||
|
||||
vListInitialise( &pxSocket->u.xTCP.xTCPWindow.xTxSegments );
|
||||
|
||||
if( nondet_bool() )
|
||||
{
|
||||
TCPSegment_t * segment = malloc( sizeof( TCPSegment_t ) );
|
||||
__CPROVER_assume( segment != NULL );
|
||||
vListInitialiseItem( &segment->xSegmentItem );
|
||||
listSET_LIST_ITEM_OWNER( &segment->xQueueItem, ( void * ) segment );
|
||||
vListInsertEnd( &pxSocket->u.xTCP.xTCPWindow.xTxSegments, &segment->xQueueItem );
|
||||
}
|
||||
|
||||
vListInitialise( &pxSocket->u.xTCP.xTCPWindow.xPriorityQueue );
|
||||
|
||||
extern List_t xSegmentList;
|
||||
|
||||
vListInitialise( &xSegmentList );
|
||||
|
||||
/****************************************************************
|
||||
* Specification and proof of CheckOptions inner loop
|
||||
****************************************************************/
|
||||
|
||||
/* Preconditions */
|
||||
|
||||
/* CBMC model of pointers limits the size of the buffer */
|
||||
__CPROVER_assume( buffer_size < CBMC_MAX_OBJECT_SIZE );
|
||||
|
||||
/* Both preconditions are required to avoid integer overflow in the */
|
||||
/* pointer offset of the pointer pucPtr + uxIndex + 8 */
|
||||
__CPROVER_assume( uxIndex <= buffer_size );
|
||||
__CPROVER_assume( uxIndex + 8 <= buffer_size );
|
||||
|
||||
/* Assuming quite a bit more about the initialization of pxSocket */
|
||||
__CPROVER_assume( pucPtr != NULL );
|
||||
__CPROVER_assume( pxSocket != NULL );
|
||||
|
||||
prvReadSackOption( pucPtr, uxIndex, pxSocket );
|
||||
|
||||
/* No postconditions required */
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
{
|
||||
"ENTRY": "CheckOptionsInner",
|
||||
"CBMCFLAGS": [
|
||||
"--unwind 1",
|
||||
"--unwindset prvTCPWindowTxCheckAck.1:2,prvTCPWindowFastRetransmit.2:2"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_WIN.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Stream_Buffer.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
#include "cbmc.h"
|
||||
|
||||
/****************************************************************
|
||||
* Signature of the function under test
|
||||
****************************************************************/
|
||||
|
||||
int32_t __CPROVER_file_local_FreeRTOS_TCP_Reception_c_prvSingleStepTCPHeaderOptions( const uint8_t * const pucPtr,
|
||||
size_t uxTotalLength,
|
||||
FreeRTOS_Socket_t * const pxSocket,
|
||||
BaseType_t xHasSYNFlag );
|
||||
|
||||
/****************************************************************
|
||||
* Declare the buffer size external to the harness so it can be
|
||||
* accessed by the preconditions of prvReadSackOption, and give the
|
||||
* buffer size an unconstrained value in the harness itself.
|
||||
****************************************************************/
|
||||
|
||||
size_t buffer_size;
|
||||
|
||||
/****************************************************************
|
||||
* Function contract proved correct by CheckOptionsInner
|
||||
****************************************************************/
|
||||
|
||||
void __CPROVER_file_local_FreeRTOS_TCP_Reception_c_prvReadSackOption( const uint8_t * const pucPtr,
|
||||
size_t uxIndex,
|
||||
FreeRTOS_Socket_t * const pxSocket )
|
||||
{
|
||||
/* Preconditions */
|
||||
__CPROVER_assert( buffer_size < CBMC_MAX_OBJECT_SIZE,
|
||||
"prvReadSackOption: buffer_size < CBMC_MAX_OBJECT_SIZE" );
|
||||
__CPROVER_assert( uxIndex <= buffer_size,
|
||||
"prvReadSackOption: uxIndex <= buffer_size" );
|
||||
__CPROVER_assert( uxIndex + 8 <= buffer_size,
|
||||
"prvReadSackOption: uxIndex + 8 <= buffer_size" );
|
||||
__CPROVER_assert( pucPtr != NULL,
|
||||
"prvReadSackOption: pucPtr != NULL" );
|
||||
__CPROVER_assert( pxSocket != NULL,
|
||||
"prvReadSackOption: pxSocket != NULL" );
|
||||
|
||||
/* No postconditions required */
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Proof of prvSingleStepTCPHeaderOptions function contract
|
||||
****************************************************************/
|
||||
|
||||
void harness()
|
||||
{
|
||||
/* Give buffer_size an unconstrained value */
|
||||
size_t buf_size;
|
||||
|
||||
buffer_size = buf_size;
|
||||
|
||||
uint8_t * pucPtr = malloc( buffer_size );
|
||||
size_t uxTotalLength;
|
||||
FreeRTOS_Socket_t * pxSocket = malloc( sizeof( FreeRTOS_Socket_t ) );
|
||||
BaseType_t xHasSYNFlag;
|
||||
|
||||
/****************************************************************
|
||||
* Specification and proof of CheckOptions outer loop
|
||||
****************************************************************/
|
||||
|
||||
/* CBMC model of pointers limits the size of the buffer */
|
||||
__CPROVER_assume( buffer_size < CBMC_MAX_OBJECT_SIZE );
|
||||
|
||||
/* Preconditions */
|
||||
__CPROVER_assume( 8 <= buffer_size ); /* ulFirst and ulLast */
|
||||
__CPROVER_assume( pucPtr != NULL );
|
||||
__CPROVER_assume( uxTotalLength <= buffer_size );
|
||||
__CPROVER_assume( pxSocket != NULL );
|
||||
|
||||
int32_t index = __CPROVER_file_local_FreeRTOS_TCP_Reception_c_prvSingleStepTCPHeaderOptions( pucPtr,
|
||||
uxTotalLength,
|
||||
pxSocket,
|
||||
xHasSYNFlag );
|
||||
|
||||
/* Postconditions */
|
||||
__CPROVER_assert( ( ( index == -1 ) || ( index == 1 ) || ( index <= uxTotalLength ) ),
|
||||
"prvSingleStepTCPHeaderOptions: index <= uxTotalLength" );
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"ENTRY": "CheckOptionsOuter",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--unwindset __CPROVER_file_local_FreeRTOS_TCP_Reception_c_prvSingleStepTCPHeaderOptions.2:32"
|
||||
],
|
||||
"OPT":
|
||||
[
|
||||
"--export-file-local-symbols"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Reception.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_WIN.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Stream_Buffer.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* FreeRTOS memory safety proofs with CBMC.
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
|
||||
/* Static members defined in FreeRTOS_DHCP.c */
|
||||
extern DHCPData_t xDHCPData;
|
||||
extern Socket_t xDHCPSocket;
|
||||
void prvCreateDHCPSocket();
|
||||
|
||||
/* Static member defined in freertos_api.c */
|
||||
#ifdef CBMC_GETNETWORKBUFFER_FAILURE_BOUND
|
||||
extern uint32_t GetNetworkBuffer_failure_count;
|
||||
#endif
|
||||
|
||||
/****************************************************************
|
||||
* The signature of the function under test.
|
||||
****************************************************************/
|
||||
|
||||
void vDHCPProcess( BaseType_t xReset,
|
||||
eDHCPState_t eExpectedState );
|
||||
|
||||
/****************************************************************
|
||||
* Abstract prvProcessDHCPReplies proved memory safe in ProcessDHCPReplies.
|
||||
****************************************************************/
|
||||
|
||||
BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType )
|
||||
{
|
||||
return nondet_BaseType();
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* The proof of vDHCPProcess
|
||||
****************************************************************/
|
||||
|
||||
void harness()
|
||||
{
|
||||
BaseType_t xReset;
|
||||
eDHCPState_t eExpectedState;
|
||||
|
||||
/****************************************************************
|
||||
* Initialize the counter used to bound the number of times
|
||||
* GetNetworkBufferWithDescriptor can fail.
|
||||
****************************************************************/
|
||||
|
||||
#ifdef CBMC_GETNETWORKBUFFER_FAILURE_BOUND
|
||||
GetNetworkBuffer_failure_count = 0;
|
||||
#endif
|
||||
|
||||
/****************************************************************
|
||||
* Assume a valid socket in most states of the DHCP state machine.
|
||||
*
|
||||
* The socket is created in the eWaitingSendFirstDiscover state.
|
||||
* xReset==True resets the state to eWaitingSendFirstDiscover.
|
||||
****************************************************************/
|
||||
|
||||
if( !( ( xDHCPData.eDHCPState == eInitialWait ) ||
|
||||
( xReset != pdFALSE ) ) )
|
||||
{
|
||||
prvCreateDHCPSocket();
|
||||
__CPROVER_assume( xDHCPSocket != NULL );
|
||||
}
|
||||
|
||||
vDHCPProcess( xReset, eExpectedState );
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
#
|
||||
# FreeRTOS memory safety proofs with CBMC.
|
||||
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation
|
||||
# files (the "Software"), to deal in the Software without
|
||||
# restriction, including without limitation the rights to use, copy,
|
||||
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
# of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://aws.amazon.com/freertos
|
||||
# http://www.FreeRTOS.org
|
||||
#
|
||||
|
||||
{
|
||||
"ENTRY": "DHCPProcess",
|
||||
|
||||
# Minimal buffer size for maximum coverage, see harness for details.
|
||||
"BUFFER_SIZE": 299,
|
||||
|
||||
# The number of times GetNetworkBufferWithDescriptor can be allowed to fail
|
||||
# (plus 1).
|
||||
"FAILURE_BOUND": 2,
|
||||
|
||||
"CBMCFLAGS": "--unwind 4 --unwindset strlen.0:11,memcmp.0:7,prvProcessDHCPReplies.0:8,prvCreatePartDHCPMessage.0:{FAILURE_BOUND} --nondet-static --flush",
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto"
|
||||
],
|
||||
|
||||
"DEF":
|
||||
[
|
||||
"BUFFER_SIZE={BUFFER_SIZE}",
|
||||
"CBMC_REQUIRE_NETWORKBUFFER_ETHERNETBUFFER_NONNULL=1",
|
||||
"CBMC_GETNETWORKBUFFER_FAILURE_BOUND={FAILURE_BOUND}"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
This is the memory safety proof for DHCPProcess function, which is the
|
||||
function that triggers the DHCP protocol.
|
||||
|
||||
The main stubs in this proof deal with buffer management, which assume
|
||||
that the buffer is large enough to accomodate a DHCP message plus a
|
||||
few additional bytes for options (which is the last, variable-sized
|
||||
field in a DHCP message). We have abstracted away sockets, concurrency
|
||||
and third-party code. For more details, please check the comments on
|
||||
the harness file.
|
||||
|
||||
This proof is a work-in-progress. Proof assumptions are described in
|
||||
the harness. The proof also assumes the following functions are
|
||||
memory safe and have no side effects relevant to the memory safety of
|
||||
this function:
|
||||
|
||||
* FreeRTOS_sendto
|
||||
* FreeRTOS_setsockopt
|
||||
* FreeRTOS_socket
|
||||
* ulRand
|
||||
* vARPSendGratuitous
|
||||
* vApplicationIPNetworkEventHook
|
||||
* vLoggingPrintf
|
||||
* vPortEnterCritical
|
||||
* vPortExitCritical
|
||||
* vReleaseNetworkBufferAndDescriptor
|
||||
* vSocketBind
|
||||
* vSocketClose
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
{ "expected-missing-functions":
|
||||
[
|
||||
"vPortEnterCritical",
|
||||
"vPortExitCritical",
|
||||
"vSocketBind",
|
||||
"vSocketClose",
|
||||
"vTaskSetTimeOutState",
|
||||
"xTaskGetTickCount",
|
||||
"xTaskGetCurrentTaskHandle",
|
||||
"xQueueGenericSend",
|
||||
"xApplicationGetRandomNumber",
|
||||
"vLoggingPrintf"
|
||||
],
|
||||
"proof-name": "DHCPProcess",
|
||||
"proof-root": "tools/cbmc/proofs"
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* FreeRTOS memory safety proofs with CBMC.
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
|
||||
/*
|
||||
* The harness test proceeds to call IsDHCPSocket with an unconstrained value
|
||||
*/
|
||||
void harness()
|
||||
{
|
||||
Socket_t xSocket;
|
||||
BaseType_t xResult;
|
||||
|
||||
xResult = xIsDHCPSocket( xSocket );
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
#
|
||||
# FreeRTOS memory safety proofs with CBMC.
|
||||
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation
|
||||
# files (the "Software"), to deal in the Software without
|
||||
# restriction, including without limitation the rights to use, copy,
|
||||
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
# of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://aws.amazon.com/freertos
|
||||
# http://www.FreeRTOS.org
|
||||
#
|
||||
|
||||
{
|
||||
"ENTRY": "IsDHCPSocket",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCP.goto"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
This is the memory safety proof for IsDCHPSocket.
|
||||
@ -0,0 +1,24 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
/* Function prvParseDNSReply is proven to be correct separately.
|
||||
* The proof can be found here: https://github.com/aws/amazon-freertos/tree/master/tools/cbmc/proofs/ParseDNSReply */
|
||||
uint32_t prvParseDNSReply( uint8_t * pucUDPPayloadBuffer,
|
||||
size_t xBufferLength,
|
||||
BaseType_t xExpected )
|
||||
{
|
||||
}
|
||||
|
||||
void harness()
|
||||
{
|
||||
NetworkBufferDescriptor_t xNetworkBuffer;
|
||||
|
||||
xNetworkBuffer.pucEthernetBuffer = malloc( sizeof( UDPPacket_t ) + sizeof( DNSMessage_t ) );
|
||||
ulDNSHandlePacket( &xNetworkBuffer );
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"ENTRY": "DNShandlePacket",
|
||||
"CBMCFLAGS": "--unwind 1",
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
|
||||
void harness()
|
||||
{
|
||||
if( ipconfigUSE_DNS_CACHE != 0 )
|
||||
{
|
||||
FreeRTOS_dnsclear();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"ENTRY": "DNSclear",
|
||||
################################################################
|
||||
# This configuration flag uses DNS cache
|
||||
"USE_CACHE":1,
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
"ipconfigUSE_DNS_CACHE={USE_CACHE}"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,171 @@
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
#include "cbmc.h"
|
||||
|
||||
uint32_t FreeRTOS_dnslookup( const char * pcHostName );
|
||||
Socket_t DNS_CreateSocket( TickType_t uxReadTimeout_ticks );
|
||||
void DNS_CloseSocket( Socket_t xDNSSocket );
|
||||
void DNS_ReadReply( Socket_t xDNSSocket,
|
||||
struct freertos_sockaddr * xAddress,
|
||||
struct xDNSBuffer * pxDNSBuf );
|
||||
uint32_t DNS_SendRequest( Socket_t xDNSSocket,
|
||||
struct freertos_sockaddr * xAddress,
|
||||
struct xDNSBuffer * pxDNSBuf );
|
||||
uint32_t DNS_ParseDNSReply( uint8_t * pucUDPPayloadBuffer,
|
||||
size_t xBufferLength,
|
||||
BaseType_t xExpected );
|
||||
|
||||
/****************************************************************
|
||||
* We abstract:
|
||||
*
|
||||
* All kernel task scheduling functions since we are doing
|
||||
* sequential verification and the sequential verification of these
|
||||
* sequential primitives is done elsewhere.
|
||||
*
|
||||
* Many methods in the FreeRTOS TCP API in stubs/freertos_api.c
|
||||
*
|
||||
* DNS_ParseDNSReply proved memory safe elsewhere
|
||||
*
|
||||
* prvCreateDNSMessage
|
||||
*
|
||||
* This proof assumes the length of pcHostName is bounded by
|
||||
* MAX_HOSTNAME_LEN. We have to bound this length because we have to
|
||||
* bound the iterations of strcmp.
|
||||
****************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
* Abstract DNS_ParseDNSReply proved memory safe in ParseDNSReply.
|
||||
*
|
||||
* We stub out his function to fill the payload buffer with
|
||||
* unconstrained data and return an unconstrained size.
|
||||
*
|
||||
* The function under test uses only the return value of this
|
||||
* function.
|
||||
****************************************************************/
|
||||
|
||||
uint32_t DNS_ParseDNSReply( uint8_t * pucUDPPayloadBuffer,
|
||||
size_t xBufferLength,
|
||||
BaseType_t xExpected )
|
||||
{
|
||||
uint32_t size;
|
||||
|
||||
__CPROVER_havoc_object( pucUDPPayloadBuffer );
|
||||
return size;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Abstract DNS_SendRequest
|
||||
*
|
||||
* We stub out this function with return constraint of true or false
|
||||
*
|
||||
****************************************************************/
|
||||
uint32_t DNS_SendRequest( Socket_t xDNSSocket,
|
||||
struct freertos_sockaddr * xAddress,
|
||||
struct xDNSBuffer * pxDNSBuf )
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
__CPROVER_assume( ret >= 0 );
|
||||
__CPROVER_assume( ret <= 1 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Abstract DNS_ReadReply
|
||||
*
|
||||
* We stub out this function which returned a dns_buffer filled with random data
|
||||
*
|
||||
****************************************************************/
|
||||
void DNS_ReadReply( Socket_t xDNSSocket,
|
||||
struct freertos_sockaddr * xAddress,
|
||||
struct xDNSBuffer * pxDNSBuf )
|
||||
{
|
||||
int len;
|
||||
|
||||
pxDNSBuf->pucPayloadBuffer = safeMalloc( len );
|
||||
|
||||
pxDNSBuf->uxPayloadLength = len;
|
||||
|
||||
__CPROVER_assume( len < CBMC_MAX_OBJECT_SIZE );
|
||||
__CPROVER_assume( pxDNSBuf->pucPayloadBuffer != NULL );
|
||||
|
||||
__CPROVER_havoc_slice( pxDNSBuf->pucPayloadBuffer, pxDNSBuf->uxPayloadSize );
|
||||
}
|
||||
|
||||
|
||||
void DNS_CloseSocket( Socket_t xDNSSocket )
|
||||
{
|
||||
}
|
||||
|
||||
Socket_t DNS_CreateSocket( TickType_t uxReadTimeout_ticks )
|
||||
{
|
||||
Socket_t sock;
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
uint32_t FreeRTOS_dnslookup( const char * pcHostName )
|
||||
{
|
||||
int ret;
|
||||
|
||||
__CPROVER_assume( ret < 0xFFFF );
|
||||
__CPROVER_assume( ret > 0 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Abstract prvCreateDNSMessage
|
||||
*
|
||||
* This function writes a header, a hostname, and a constant amount of
|
||||
* data into the payload buffer, and returns the amount of data
|
||||
* written. This abstraction just fills the entire buffer with
|
||||
* unconstrained data and returns and unconstrained length.
|
||||
****************************************************************/
|
||||
|
||||
size_t prvCreateDNSMessage( uint8_t * pucUDPPayloadBuffer,
|
||||
const char * pcHostName,
|
||||
TickType_t uxIdentifier )
|
||||
{
|
||||
__CPROVER_havoc_object( pucUDPPayloadBuffer );
|
||||
size_t size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* The proof for FreeRTOS_gethostbyname.
|
||||
****************************************************************/
|
||||
|
||||
void harness()
|
||||
{
|
||||
size_t len;
|
||||
|
||||
__CPROVER_assume( len <= MAX_HOSTNAME_LEN );
|
||||
char * pcHostName = safeMalloc( len );
|
||||
|
||||
__CPROVER_assume( len > 0 ); /* prvProcessDNSCache strcmp */
|
||||
__CPROVER_assume( pcHostName != NULL );
|
||||
pcHostName[ len - 1 ] = NULL;
|
||||
|
||||
FreeRTOS_gethostbyname( pcHostName );
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"ENTRY": "DNSgetHostByName",
|
||||
|
||||
################################################################
|
||||
# This configuration sets callback to 0.
|
||||
# It also sets MAX_HOSTNAME_LEN to 10 to bound strcmp.
|
||||
# According to the specification MAX_HOST_NAME is upto 255.
|
||||
|
||||
"callback": 0,
|
||||
"MAX_HOSTNAME_LEN": 10,
|
||||
"HOSTNAME_UNWIND": "__eval {MAX_HOSTNAME_LEN} + 1",
|
||||
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--unwindset prvCreateDNSMessage.0:{HOSTNAME_UNWIND},prvCreateDNSMessage.1:{HOSTNAME_UNWIND},strlen.0:{HOSTNAME_UNWIND},__builtin___strcpy_chk.0:{HOSTNAME_UNWIND},strcmp.0:{HOSTNAME_UNWIND},strcpy.0:{HOSTNAME_UNWIND}",
|
||||
"--unwindset prvGetHostByNameOp_WithRetry.0:{HOSTNAME_UNWIND}",
|
||||
"--nondet-static"
|
||||
],
|
||||
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Parser.goto"
|
||||
],
|
||||
|
||||
"DEF":
|
||||
[
|
||||
"ipconfigDNS_USE_CALLBACKS={callback}",
|
||||
"MAX_HOSTNAME_LEN={MAX_HOSTNAME_LEN}"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
{ "expected-missing-functions":
|
||||
[
|
||||
"vLoggingPrintf",
|
||||
"xApplicationGetRandomNumber",
|
||||
"xTaskGetTickCount"
|
||||
],
|
||||
"proof-name": "DNSgetHostByName",
|
||||
"proof-root": "tools/cbmc/proofs"
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_UDP_IP.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
#include "cbmc.h"
|
||||
|
||||
/****************************************************************
|
||||
* We abstract:
|
||||
*
|
||||
* All kernel task scheduling functions since we are doing
|
||||
* sequential verification and the sequential verification of these
|
||||
* sequential primitives is done elsewhere.
|
||||
*
|
||||
* Many methods in the FreeRTOS TCP API in stubs/freertos_api.c
|
||||
*
|
||||
* DNS_ParseDNSReply proved memory safe elsewhere
|
||||
*
|
||||
* prvCreateDNSMessage
|
||||
*
|
||||
* This proof assumes the length of pcHostName is bounded by
|
||||
* MAX_HOSTNAME_LEN. We have to bound this length because we have to
|
||||
* bound the iterations of strcmp.
|
||||
****************************************************************/
|
||||
|
||||
/****************************************************************
|
||||
* Abstract DNS_ParseDNSReply proved memory safe in ParseDNSReply.
|
||||
*
|
||||
* We stub out his function to fill the payload buffer with
|
||||
* unconstrained data and return an unconstrained size.
|
||||
*
|
||||
* The function under test uses only the return value of this
|
||||
* function.
|
||||
****************************************************************/
|
||||
|
||||
uint32_t DNS_ParseDNSReply( uint8_t * pucUDPPayloadBuffer,
|
||||
size_t xBufferLength,
|
||||
BaseType_t xExpected )
|
||||
{
|
||||
__CPROVER_assert( pucUDPPayloadBuffer != NULL,
|
||||
"Precondition: pucUDPPayloadBuffer != NULL" );
|
||||
|
||||
__CPROVER_havoc_object( pucUDPPayloadBuffer );
|
||||
return nondet_uint32();
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Abstract prvCreateDNSMessage
|
||||
*
|
||||
* This function writes a header, a hostname, and a constant amount of
|
||||
* data into the payload buffer, and returns the amount of data
|
||||
* written. This abstraction just fills the entire buffer with
|
||||
* unconstrained data and returns and unconstrained length.
|
||||
****************************************************************/
|
||||
|
||||
size_t prvCreateDNSMessage( uint8_t * pucUDPPayloadBuffer,
|
||||
const char * pcHostName,
|
||||
TickType_t uxIdentifier )
|
||||
{
|
||||
__CPROVER_assert( pucUDPPayloadBuffer != NULL,
|
||||
"Precondition: pucUDPPayloadBuffer != NULL" );
|
||||
__CPROVER_assert( pcHostName != NULL,
|
||||
"Precondition: pcHostName != NULL" );
|
||||
|
||||
__CPROVER_havoc_object( pucUDPPayloadBuffer );
|
||||
return nondet_sizet();
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* A stub for a function callback.
|
||||
****************************************************************/
|
||||
|
||||
void func( const char * pcHostName,
|
||||
void * pvSearchID,
|
||||
uint32_t ulIPAddress )
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* The proof for FreeRTOS_gethostbyname_a.
|
||||
****************************************************************/
|
||||
|
||||
void harness()
|
||||
{
|
||||
size_t len;
|
||||
|
||||
__CPROVER_assume( len <= MAX_HOSTNAME_LEN );
|
||||
char * pcHostName = safeMalloc( len );
|
||||
|
||||
__CPROVER_assume( len > 0 ); /* prvProcessDNSCache strcmp */
|
||||
__CPROVER_assume( pcHostName != NULL );
|
||||
pcHostName[ len - 1 ] = NULL;
|
||||
|
||||
FOnDNSEvent pCallback = func;
|
||||
TickType_t xTimeout;
|
||||
void * pvSearchID;
|
||||
|
||||
FreeRTOS_gethostbyname_a( pcHostName, pCallback, pvSearchID, xTimeout );
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
{
|
||||
"ENTRY": "DNSgetHostByName_a",
|
||||
################################################################
|
||||
# This configuration flag sets callback to 1. It also sets MAX_HOSTNAME_LEN to 10 and MAX_REQ_SIZE to 50 for performance issues.
|
||||
# According to the specification MAX_HOST_NAME is upto 255.
|
||||
"callback": 1,
|
||||
"MAX_HOSTNAME_LEN": 10,
|
||||
"HOSTNAME_UNWIND": "__eval {MAX_HOSTNAME_LEN} + 1",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--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}",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Parser.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
"ipconfigDNS_USE_CALLBACKS={callback}",
|
||||
"MAX_HOSTNAME_LEN={MAX_HOSTNAME_LEN}",
|
||||
# This value is defined only when ipconfigUSE_DNS_CACHE==1
|
||||
"ipconfigDNS_CACHE_NAME_LENGTH=254"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
{ "expected-missing-functions":
|
||||
[
|
||||
"vLoggingPrintf",
|
||||
"xApplicationGetRandomNumber",
|
||||
"vListInsertEnd",
|
||||
"vTaskSetTimeOutState",
|
||||
"vTaskSuspendAll",
|
||||
"xTaskGetTickCount",
|
||||
"xTaskResumeAll"
|
||||
],
|
||||
"proof-name": "DNSgetHostByName_a",
|
||||
"proof-root": "tools/cbmc/proofs"
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "list.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
|
||||
/* This proof assumes the length of pcHostName is bounded by MAX_HOSTNAME_LEN. This also abstracts the concurrency. */
|
||||
|
||||
void vDNSInitialise( void );
|
||||
|
||||
void vDNSSetCallBack( const char * pcHostName,
|
||||
void * pvSearchID,
|
||||
FOnDNSEvent pCallbackFunction,
|
||||
TickType_t xTimeout,
|
||||
TickType_t xIdentifier );
|
||||
|
||||
void * safeMalloc( size_t xWantedSize ) /* Returns a NULL pointer if the wanted size is 0. */
|
||||
{
|
||||
if( xWantedSize == 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t byte;
|
||||
|
||||
return byte ? malloc( xWantedSize ) : NULL;
|
||||
}
|
||||
|
||||
/* Abstraction of xTaskCheckForTimeOut from task pool. This also abstracts the concurrency. */
|
||||
BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
||||
TickType_t * const pxTicksToWait )
|
||||
{
|
||||
}
|
||||
|
||||
/* Abstraction of xTaskResumeAll from task pool. This also abstracts the concurrency. */
|
||||
BaseType_t xTaskResumeAll( void )
|
||||
{
|
||||
}
|
||||
|
||||
/* The function func mimics the callback function.*/
|
||||
void func( const char * pcHostName,
|
||||
void * pvSearchID,
|
||||
uint32_t ulIPAddress )
|
||||
{
|
||||
}
|
||||
|
||||
void harness()
|
||||
{
|
||||
vDNSInitialise(); /* We initialize the callbacklist in order to be able to check for functions that timed out. */
|
||||
size_t pvSearchID;
|
||||
FOnDNSEvent pCallback = func;
|
||||
TickType_t xTimeout;
|
||||
TickType_t xIdentifier;
|
||||
size_t len;
|
||||
|
||||
__CPROVER_assume( len >= 0 && len <= MAX_HOSTNAME_LEN );
|
||||
char * pcHostName = safeMalloc( len );
|
||||
|
||||
if( len && pcHostName )
|
||||
{
|
||||
pcHostName[ len - 1 ] = NULL;
|
||||
}
|
||||
|
||||
vDNSSetCallBack( pcHostName, &pvSearchID, pCallback, xTimeout, xIdentifier ); /* Add an item to be able to check the cancel function if the list is non-empty. */
|
||||
FreeRTOS_gethostbyname_cancel( &pvSearchID );
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
{
|
||||
"ENTRY": "DNSgetHostByName_cancel",
|
||||
################################################################
|
||||
# This configuration flag sets callback to 1. It also sets MAX_HOSTNAME_LEN to 10 for performance issues.
|
||||
# According to the specification MAX_HOST_NAME is upto 255.
|
||||
"callback": 1,
|
||||
"MAX_HOSTNAME_LEN": 10,
|
||||
"HOSTNAME_UNWIND": "__eval {MAX_HOSTNAME_LEN} + 1",
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--unwindset prvProcessDNSCache.0:5,strlen.0:{HOSTNAME_UNWIND},__builtin___strcpy_chk.0:{HOSTNAME_UNWIND},vDNSCheckCallBack.0:2,strcpy.0:{HOSTNAME_UNWIND}",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
"ipconfigDNS_USE_CALLBACKS={callback}",
|
||||
"MAX_HOSTNAME_LEN={MAX_HOSTNAME_LEN}",
|
||||
# This value is defined only when ipconfigUSE_DNS_CACHE==1
|
||||
"ipconfigDNS_CACHE_NAME_LENGTH=254"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "list.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
/* This assumes that the length of the hostname is bounded by MAX_HOSTNAME_LEN. */
|
||||
void * safeMalloc( size_t xWantedSize )
|
||||
{
|
||||
if( xWantedSize == 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t byte;
|
||||
|
||||
return byte ? malloc( xWantedSize ) : NULL;
|
||||
}
|
||||
|
||||
void harness()
|
||||
{
|
||||
if( ipconfigUSE_DNS_CACHE != 0 )
|
||||
{
|
||||
size_t len;
|
||||
__CPROVER_assume( len >= 0 && len <= MAX_HOSTNAME_LEN );
|
||||
char * pcHostName = safeMalloc( len ); /* malloc is replaced by safeMalloc */
|
||||
|
||||
if( len && pcHostName )
|
||||
{
|
||||
pcHostName[ len - 1 ] = NULL;
|
||||
}
|
||||
|
||||
if( pcHostName ) /* guarding against NULL pointer */
|
||||
{
|
||||
FreeRTOS_dnslookup( pcHostName );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
{
|
||||
"ENTRY": "DNSlookup",
|
||||
################################################################
|
||||
# This configuration uses DNS cache and the MAX_HOSTNAME_LEN is set to 255 according to the specification
|
||||
"MAX_HOSTNAME_LEN": 255,
|
||||
"HOSTNAME_UNWIND": "__eval {MAX_HOSTNAME_LEN} + 1",
|
||||
"USE_CACHE": 1,
|
||||
"CBMCFLAGS":
|
||||
[
|
||||
"--unwind 1",
|
||||
"--unwindset prvProcessDNSCache.0:5,strcmp.0:{HOSTNAME_UNWIND}",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto"
|
||||
],
|
||||
"DEF":
|
||||
[
|
||||
"ipconfigUSE_DNS_CACHE={USE_CACHE}",
|
||||
"MAX_HOSTNAME_LEN={MAX_HOSTNAME_LEN}"
|
||||
],
|
||||
"OPT" : "-m32"
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
#
|
||||
# FreeRTOS memory safety proofs with CBMC.
|
||||
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation
|
||||
# files (the "Software"), to deal in the Software without
|
||||
# restriction, including without limitation the rights to use, copy,
|
||||
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
# of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# http://aws.amazon.com/freertos
|
||||
# http://www.FreeRTOS.org
|
||||
#
|
||||
|
||||
{
|
||||
"ENTRY": "SendEventToIPTask",
|
||||
"CBMCFLAGS": [
|
||||
"--unwind 1",
|
||||
"--nondet-static"
|
||||
],
|
||||
"OBJS":
|
||||
[
|
||||
"$(ENTRY)_harness.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
This is the memory safety proof for xSendEventToIPTask, a function used
|
||||
for sending different events to IP-Task. We have abstracted away queues.
|
||||
|
||||
This proof is a work-in-progress. Proof assumptions are described in
|
||||
the harness. The proof also assumes the following functions are
|
||||
memory safe and have no side effects relevant to the memory safety of
|
||||
this function:
|
||||
|
||||
* uxQueueMessagesWaiting
|
||||
* xQueueGenericSend
|
||||
|
||||
The coverage is imperfect (97%) because xSendEventToIPTask always
|
||||
calls xSendEventStructToIPTask with xTimeout==0.
|
||||
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* FreeRTOS memory safety proofs with CBMC.
|
||||
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
|
||||
/* The harness test proceeds to call SendEventToIPTask with an unconstrained value */
|
||||
void harness()
|
||||
{
|
||||
eIPEvent_t eEvent;
|
||||
|
||||
xSendEventToIPTask( eEvent );
|
||||
}
|
||||
@ -0,0 +1,174 @@
|
||||
default: report
|
||||
|
||||
# ____________________________________________________________________
|
||||
# CBMC binaries
|
||||
#
|
||||
|
||||
GOTO_CC = @GOTO_CC@
|
||||
GOTO_INSTRUMENT = goto-instrument
|
||||
GOTO_ANALYZER = goto-analyzer
|
||||
VIEWER = cbmc-viewer
|
||||
|
||||
# ____________________________________________________________________
|
||||
# Variables
|
||||
#
|
||||
# Naming scheme:
|
||||
# ``````````````
|
||||
# FOO is the concatenation of the following:
|
||||
# FOO2: Set of command line
|
||||
# C_FOO: Value of $FOO common to all harnesses, set in this file
|
||||
# O_FOO: Value of $FOO specific to the OS we're running on, set in the
|
||||
# makefile for the operating system
|
||||
# H_FOO: Value of $FOO specific to a particular harness, set in the
|
||||
# makefile for that harness
|
||||
|
||||
ENTRY = $(H_ENTRY)
|
||||
OBJS = $(H_OBJS)
|
||||
|
||||
INC = \
|
||||
$(INC2) \
|
||||
$(C_INC) $(O_INC) $(H_INC) \
|
||||
# empty
|
||||
|
||||
CFLAGS = \
|
||||
$(CFLAGS2) \
|
||||
$(C_DEF) $(O_DEF) $(H_DEF) $(DEF) \
|
||||
$(C_OPT) $(O_OPT) $(H_OPT) $(OPT) \
|
||||
-m32 \
|
||||
# empty
|
||||
|
||||
CBMCFLAGS = \
|
||||
--flush \
|
||||
$(CBMCFLAGS2) \
|
||||
$(C_CBMCFLAGS) $(O_CBMCFLAGS) $(H_CBMCFLAGS) \
|
||||
# empty
|
||||
|
||||
INSTFLAGS = \
|
||||
$(INSTFLAGS2) \
|
||||
$(C_INSTFLAGS) $(O_INSTFLAGS) $(H_INSTFLAGS) \
|
||||
# empty
|
||||
|
||||
# ____________________________________________________________________
|
||||
# Rules
|
||||
#
|
||||
# Rules for patching
|
||||
|
||||
patch:
|
||||
cd $(PROOFS)/../patches && ./patch.py
|
||||
|
||||
unpatch:
|
||||
cd $(PROOFS)/../patches && ./unpatch.py
|
||||
|
||||
# ____________________________________________________________________
|
||||
# Rules
|
||||
#
|
||||
# Rules for building the CBMC harness
|
||||
|
||||
C_SOURCES = $(patsubst %.goto,%.c,$(H_OBJS_EXCEPT_HARNESS))
|
||||
|
||||
# Build each goto-binary out-of-source (i.e. in a 'gotos' directory
|
||||
# underneath each proof directory, to make it safe to build all proofs
|
||||
# in parallel
|
||||
OOS_OBJS = $(patsubst %.c,gotos/%.goto,$(C_SOURCES))
|
||||
|
||||
CWD=$(abspath .)
|
||||
|
||||
gotos/%.goto: %.c
|
||||
mkdir -p $(dir $@)
|
||||
$(GOTO_CC) @COMPILE_ONLY@ @RULE_OUTPUT@ $(INC) $(CFLAGS) @RULE_INPUT@
|
||||
|
||||
queue_datastructure.h: gotos/$(FREERTOS)/freertos_kernel/queue.goto
|
||||
python3 @TYPE_HEADER_SCRIPT@ --binary $(CWD)/gotos$(FREERTOS)/freertos_kernel/queue.goto --c-file $(FREERTOS)/freertos_kernel/queue.c
|
||||
|
||||
$(ENTRY)_harness.goto: $(ENTRY)_harness.c $(H_GENERATE_HEADER)
|
||||
$(GOTO_CC) @COMPILE_ONLY@ @RULE_OUTPUT@ $(INC) $(CFLAGS) $(ENTRY)_harness.c
|
||||
|
||||
$(ENTRY)1.goto: $(ENTRY)_harness.goto $(OOS_OBJS)
|
||||
$(GOTO_CC) @COMPILE_LINK@ @RULE_OUTPUT@ --function harness @RULE_INPUT@
|
||||
|
||||
$(ENTRY)2.goto: $(ENTRY)1.goto
|
||||
$(GOTO_INSTRUMENT) --add-library @RULE_INPUT@ @RULE_OUTPUT@ \
|
||||
> $(ENTRY)2.txt 2>&1
|
||||
|
||||
$(ENTRY)3.goto: $(ENTRY)2.goto
|
||||
$(GOTO_INSTRUMENT) --drop-unused-functions @RULE_INPUT@ @RULE_OUTPUT@ \
|
||||
> $(ENTRY)3.txt 2>&1
|
||||
|
||||
$(ENTRY)4.goto: $(ENTRY)3.goto
|
||||
$(GOTO_INSTRUMENT) $(INSTFLAGS) --slice-global-inits @RULE_INPUT@ @RULE_OUTPUT@ \
|
||||
> $(ENTRY)4.txt 2>&1
|
||||
# ____________________________________________________________________
|
||||
# After running goto-instrument to remove function bodies the unused
|
||||
# functions need to be dropped again.
|
||||
|
||||
$(ENTRY)5.goto: $(ENTRY)4.goto
|
||||
$(GOTO_INSTRUMENT) --drop-unused-functions @RULE_INPUT@ @RULE_OUTPUT@ \
|
||||
> $(ENTRY)5.txt 2>&1
|
||||
|
||||
$(ENTRY).goto: $(ENTRY)5.goto
|
||||
@CP@ @RULE_INPUT@ @RULE_OUTPUT@
|
||||
|
||||
# ____________________________________________________________________
|
||||
# Rules
|
||||
#
|
||||
# Rules for running CBMC
|
||||
|
||||
goto:
|
||||
$(MAKE) -B $(ENTRY).goto
|
||||
|
||||
# Ignore the return code for CBMC, so that we can still generate the
|
||||
# report if the proof failed. If the proof failed, we separately fail
|
||||
# the entire job using the check-cbmc-result rule.
|
||||
cbmc.txt: $(ENTRY).goto
|
||||
-cbmc $(CBMCFLAGS) $(SOLVER) --unwinding-assertions --trace @RULE_INPUT@ > $@ 2>&1
|
||||
|
||||
property.xml: $(ENTRY).goto
|
||||
cbmc $(CBMCFLAGS) --unwinding-assertions --show-properties --xml-ui @RULE_INPUT@ > $@ 2>&1
|
||||
|
||||
coverage.xml: $(ENTRY).goto
|
||||
cbmc $(CBMCFLAGS) --cover location --xml-ui @RULE_INPUT@ > $@ 2>&1
|
||||
|
||||
cbmc: cbmc.txt
|
||||
|
||||
property: property.xml
|
||||
|
||||
coverage: coverage.xml
|
||||
|
||||
report: cbmc.txt property.xml coverage.xml
|
||||
$(VIEWER) \
|
||||
--goto $(ENTRY).goto \
|
||||
--srcdir $(FREERTOS_PLUS_TCP) \
|
||||
--blddir $(FREERTOS_PLUS_TCP) \
|
||||
--htmldir html \
|
||||
--srcexclude "(.@FORWARD_SLASH@doc|.@FORWARD_SLASH@tests|.@FORWARD_SLASH@vendors)" \
|
||||
--result cbmc.txt \
|
||||
--property property.xml \
|
||||
--block coverage.xml
|
||||
|
||||
# This rule depends only on cbmc.txt and has no dependents, so it will
|
||||
# not block the report from being generated if it fails. This rule is
|
||||
# intended to fail if and only if the CBMC safety check that emits
|
||||
# cbmc.txt yielded a proof failure.
|
||||
check-cbmc-result: cbmc.txt
|
||||
grep -e "^VERIFICATION SUCCESSFUL" $^
|
||||
|
||||
# ____________________________________________________________________
|
||||
# Rules
|
||||
#
|
||||
# Rules for cleaning up
|
||||
|
||||
clean:
|
||||
@RM@ $(OBJS) $(ENTRY).goto
|
||||
@RM@ $(ENTRY)[0-9].goto $(ENTRY)[0-9].txt
|
||||
@RM@ cbmc.txt property.xml coverage.xml TAGS TAGS-*
|
||||
@RM@ *~ \#*
|
||||
@RM@ queue_datastructure.h
|
||||
|
||||
|
||||
veryclean: clean
|
||||
@RM_RECURSIVE@ html
|
||||
@RM_RECURSIVE@ gotos
|
||||
|
||||
distclean: veryclean
|
||||
cd $(PROOFS)/../patches && ./unpatch.py
|
||||
cd $(PROOFS) && ./make-remove-makefiles.py
|
||||
@ -0,0 +1,45 @@
|
||||
{
|
||||
"FREERTOS_PLUS_TCP": [ " ../../.." ],
|
||||
"PROOFS": [ "." ],
|
||||
|
||||
"DEF ": [
|
||||
"WIN32",
|
||||
"WINVER=0x400",
|
||||
"_CONSOLE",
|
||||
"_CRT_SECURE_NO_WARNINGS",
|
||||
"_DEBUG",
|
||||
"_WIN32_WINNT=0x0500",
|
||||
"__PRETTY_FUNCTION__=__FUNCTION__",
|
||||
"__free_rtos__",
|
||||
|
||||
"CBMC",
|
||||
"'configASSERT(X)=__CPROVER_assert(X,\"Assertion Error\")'",
|
||||
"'configPRECONDITION(X)=__CPROVER_assume(X)'",
|
||||
"'_static='",
|
||||
"'_volatile='"
|
||||
],
|
||||
|
||||
"INC ": [
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/include",
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/portable/MSVC-MingW",
|
||||
"$(FREERTOS_PLUS_TCP)/source/include",
|
||||
"$(FREERTOS_PLUS_TCP)/source/portable/Compiler/MSVC",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/include",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/patches",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/windows",
|
||||
"$(FREERTOS_PLUS_TCP)/test/cbmc/windows2"
|
||||
],
|
||||
|
||||
"CBMCFLAGS ": [
|
||||
"--object-bits 7",
|
||||
"--32",
|
||||
"--bounds-check",
|
||||
"--pointer-check"
|
||||
],
|
||||
|
||||
"FORWARD_SLASH": ["/"],
|
||||
|
||||
"TYPE_HEADERS": [
|
||||
"$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/queue.c"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
{
|
||||
"GOTO_CC": [
|
||||
"goto-cc"
|
||||
],
|
||||
"COMPILE_LINK": [
|
||||
"-o"
|
||||
],
|
||||
"COMPILE_ONLY": [
|
||||
"-c",
|
||||
"-o"
|
||||
],
|
||||
"RULE_INPUT": [
|
||||
"$^"
|
||||
],
|
||||
"RULE_OUTPUT": [
|
||||
"$@"
|
||||
],
|
||||
"RULE_GOTO": [
|
||||
"%.goto : %.c"
|
||||
],
|
||||
"INC": [
|
||||
"$(PROOFS)/../windows"
|
||||
],
|
||||
"RM": [
|
||||
"$(RM)"
|
||||
],
|
||||
"RM_RECURSIVE": [
|
||||
"$(RM) -r"
|
||||
],
|
||||
"CP": [
|
||||
"cp"
|
||||
],
|
||||
"TYPE_HEADER_SCRIPT": [
|
||||
"$(PROOFS)/make_type_header_files.py"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
{
|
||||
"DEF": [
|
||||
"WIN32"
|
||||
],
|
||||
"GOTO_CC": [
|
||||
"goto-cl"
|
||||
],
|
||||
"COMPILE_LINK": [
|
||||
"/Fe"
|
||||
],
|
||||
"COMPILE_ONLY": [
|
||||
"/c",
|
||||
"/Fo"
|
||||
],
|
||||
"RULE_INPUT": [
|
||||
"$**"
|
||||
],
|
||||
"RULE_OUTPUT": [
|
||||
"$@"
|
||||
],
|
||||
"RULE_GOTO": [
|
||||
".c.goto:"
|
||||
],
|
||||
"OPT": [
|
||||
"/wd4210",
|
||||
"/wd4127",
|
||||
"/wd4214",
|
||||
"/wd4201",
|
||||
"/wd4244",
|
||||
"/wd4310"
|
||||
],
|
||||
"RM": [
|
||||
"del"
|
||||
],
|
||||
"RM_RECURSIVE": [
|
||||
"del /s"
|
||||
],
|
||||
"CP": [
|
||||
"copy"
|
||||
],
|
||||
"TYPE_HEADER_SCRIPT": [
|
||||
"$(PROOFS)\\make_type_header_files.py"
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user